New tournament form in progress

This commit is contained in:
Claude Brisson
2023-06-14 13:58:00 +02:00
parent 288069a780
commit c2a91a7b37
42 changed files with 334 additions and 15 deletions

View File

@@ -1,10 +1,10 @@
@import "/lib/fomantic-ui-2.8.7/semantic.css" layer(semantic); @import "/lib/fomantic-ui-2.9.2/semantic.min.css" layer(semantic);
@layer pairgoth { @layer pairgoth {
/* general styles */ /* general styles */
body { body {
font-size: clamp(12px, .8rem + .25vw, 20px); font-size: clamp(14px, 1rem + 1vw, 24px);
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
margin: 0; margin: 0;
@@ -30,6 +30,7 @@
height: 3em; height: 3em;
width: 100%; width: 100%;
position: relative; position: relative;
align-items: flex-start;
justify-content: space-between; justify-content: space-between;
#logo { #logo {
height: 100%; height: 100%;
@@ -41,13 +42,15 @@
} }
#center { #center {
max-width: clamp(800px, 80vw, 100vw);
flex: 1; flex: 1;
overflow: auto; overflow: auto;
#inner { #inner {
max-width: clamp(800px, 80vw, 100vw);
display: flex; display: flex;
flex-flow: column nowrap; flex-flow: column nowrap;
align-items: center; align-items: center;
margin-left: auto;
margin-right: auto;
} }
} }
@@ -63,13 +66,53 @@
padding: 0.5em; padding: 0.5em;
} }
/* buttons */ /* modal and dimmer */
button { #dimmer {
font-size: inherit; position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: black;
opacity: 0;
transition: opacity 0.5s;
z-index: 1000;
pointer-events: none;
} }
button.floating { body.dimmed #dimmer {
display: block;
opacity: 0.85;
pointer-events: all;
}
.ui.modal {
display: block;
opacity: 0;
transition: opacity 0.5s;
pointer-events: none;
}
.ui.modal .header {
font-size: 1em;
align-items: baseline;
justify-content: space-around;
flex-wrap: wrap;
}
.active.ui.modal {
font-size: 1em;
opacity: 1;
pointer-events: all;
}
/* buttons */
.button {
font-size: 1em;
}
.button.floating {
box-shadow: 0px 8px 8px -5px rgba(0,0,0,35%); box-shadow: 0px 8px 8px -5px rgba(0,0,0,35%);
transition: all 0.3s; transition: all 0.3s;
&.white { &.white {
@@ -88,13 +131,16 @@
} }
/* languages */ /* languages */
#lang { #lang {
position: relative; position: relative;
cursor: pointer;
transform: scale(1.2);
#lang-list { #lang-list {
position: absolute; position: absolute;
display: none; display: none;
top:100%; top:100%;
left: -200%; right: 1em;
flex-flow: column nowrap; flex-flow: column nowrap;
padding: 0.5em; padding: 0.5em;
gap: 0.5em; gap: 0.5em;
@@ -106,6 +152,7 @@
} }
a { a {
display: inline-block; display: inline-block;
white-space: nowrap;
text-align: center; text-align: center;
i { i {
vertical-align: middle; vertical-align: middle;
@@ -114,4 +161,24 @@
} }
} }
/* UI fixes */
.ui.form, .ui.segment, .ui.form .field > label { font-size: 1em; }
span > input[type="radio"] { vertical-align: text-top; }
span > input[type="text"] { vertical-align: baseline; width: initial; }
span > input.date { vertical-align: baseline; width: 8em; }
.step, .step .title { font-size: 1em; }
.step:before { font-size: 1em; }
.step.description { font-size: 0.8em; }
.step:first-child { padding-left: 1em; }
.step:last-child { padding-right: 1em; }
.step .description { display: none; }
input[type="number"] {
padding: 0.2em 0.1em 0.2em 1em;
vertical-align: baseline;
width: 3.5em;
}
} }

View File

@@ -8,6 +8,7 @@
<link rel="icon" type="image/x-icon" href="/favicon.ico"> <link rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="stylesheet" href="/lib/fork-awesome-1.2.0/fork-awesome.min.css"> <link rel="stylesheet" href="/lib/fork-awesome-1.2.0/fork-awesome.min.css">
<link rel="stylesheet" href="/css/main.css"> <link rel="stylesheet" href="/css/main.css">
<script type="text/javascript" src="/js/domhelper.js"></script>
</head> </head>
<body class="vert flex"> <body class="vert flex">
<div id="header" class="horz flex"> <div id="header" class="horz flex">
@@ -36,9 +37,9 @@
<div id="version">pairgoth v0.1</div> <div id="version">pairgoth v0.1</div>
<div id="contact"><a href="mailto:pairgoth@jeudego.org">contact</a></div> <div id="contact"><a href="mailto:pairgoth@jeudego.org">contact</a></div>
</div> </div>
<div id="dimmer"></div>
<script type="text/javascript" src="/js/store2-2.14.2.min.js"></script> <script type="text/javascript" src="/js/store2-2.14.2.min.js"></script>
<script type="text/javascript" src="/js/tablesort-5.4.0.min.js"></script> <script type="text/javascript" src="/js/tablesort-5.4.0.min.js"></script>
<script type="text/javascript" src="/js/domhelper.js"></script>
<script type="text/javascript" src="/js/formproxy.js"></script> <script type="text/javascript" src="/js/formproxy.js"></script>
<script type="text/javascript" src="/js/api.js"></script> <script type="text/javascript" src="/js/api.js"></script>
<script type="text/javascript" src="/js/main.js"></script> <script type="text/javascript" src="/js/main.js"></script>

View File

@@ -12,3 +12,61 @@
</button> </button>
</div> </div>
#end #end
##
## New Tournament dialog
##
<div id="new-tournament" class="ui fullscreen modal">
<i class="close icon"></i>
<div class="horz flex header">
<span>New tournament</span>
<div class="ui ordered unstackable steps">
<div class="active step">
<div class="content">
<div class="title">Infos</div>
<div class="description">name, place and date</div>
</div>
</div>
<div class="step">
<div class="content">
<div class="title">Type</div>
<div class="description">teams or players, rounds</div>
</div>
</div>
<div class="step">
<div class="content">
<div class="title">Pairing</div>
<div class="description">pairing system</div>
</div>
</div>
</div>
</div>
<div class="scrolling content">
#parse('tournament-form.inc.html')
</div>
<div class="actions">
<button class="ui cancel black floating button">Cancel</button>
<button class="ui next green right labeled icon floating button">
<i class="checkmark icon"></i>
Next
</button>
</div></div>
<script type="text/javascript">
const lang = '${request.lang}';
// #[[
onLoad(() => {
$('#new').on('click', e => {
$('#new-tournament').modal(true);
});
new DateRangePicker($('#date-range')[0], {
language: lang
});
$('#new-tournament .tab.segment:first-child').addClass('active');
});
// ]]#
</script>
<!-- date range picker -->
<script type="text/javascript" src="/lib/datepicker-1.3.3/datepicker-full.min.js"></script>
<script type="text/javascript" src="/lib/datepicker-1.3.3/locales/${request.lang}.js"></script>
<link rel="stylesheet" href="/lib/datepicker-1.3.3/datepicker.min.css">

View File

@@ -1,3 +1,5 @@
// This small library is meant to be a lightweight replacement of jQuery basic functions.
window.$ = document.querySelectorAll.bind(document); window.$ = document.querySelectorAll.bind(document);
Node.prototype.on = window.on = function (eventNames, fn) { Node.prototype.on = window.on = function (eventNames, fn) {
let events = eventNames.split(' ') let events = eventNames.split(' ')
@@ -5,31 +7,51 @@ Node.prototype.on = window.on = function (eventNames, fn) {
let name = events[i]; let name = events[i];
this.addEventListener(name, fn); this.addEventListener(name, fn);
} }
return this;
}; };
NodeList.prototype.__proto__ = Array.prototype; NodeList.prototype.__proto__ = Array.prototype;
NodeList.prototype.on = NodeList.prototype.addEventListener = function (eventNames, fn) { NodeList.prototype.on = NodeList.prototype.addEventListener = function (eventNames, fn) {
this.forEach(function (elem, i) { this.forEach(function (elem, i) {
elem.on(eventNames, fn); elem.on(eventNames, fn);
}); });
return this;
} }
NodeList.prototype.addClass = function(className) { NodeList.prototype.addClass = function(className) {
this.forEach(function (elem, i) { this.forEach(function (elem, i) {
elem.classList.add(className); elem.classList.add(className);
}); });
return this;
}
Element.prototype.addClass = function(className) {
this.classList.add(className);
return this;
} }
NodeList.prototype.removeClass = function(className) { NodeList.prototype.removeClass = function(className) {
this.forEach(function (elem, i) { this.forEach(function (elem, i) {
elem.classList.remove(className); elem.classList.remove(className);
}); });
return this;
}
Element.prototype.removeClass = function(className) {
this.classList.remove(className);
return this;
} }
NodeList.prototype.toggleClass = function(className) { NodeList.prototype.toggleClass = function(className) {
this.forEach(function (elem, i) { this.forEach(function (elem, i) {
elem.classList.toggle(className); elem.classList.toggle(className);
}); });
return this;
}
Element.prototype.toggleClass = function(className) {
this.classList.toggle(className);
return this;
} }
NodeList.prototype.hasClass = function(className) { NodeList.prototype.hasClass = function(className) {
return this.item(0).classList.contains(className); return this.item(0).classList.contains(className);
} }
Element.prototype.toggleClass = function(className) {
this.classList.contains(className);
}
Node.prototype.offset = function() { Node.prototype.offset = function() {
let _x = 0; let _x = 0;
let _y = 0; let _y = 0;
@@ -42,21 +64,34 @@ Node.prototype.offset = function() {
return { top: _y, left: _x }; return { top: _y, left: _x };
} }
NodeList.prototype.offset = function() { NodeList.prototype.offset = function() {
this.item(0).offset() // CB TODO review this.item(0).offset();
} }
Element.prototype.attr = function (key) { Element.prototype.attr = function (key) {
return this.attributes[key].value return this.attributes[key].value;
} }
NodeList.prototype.attr = function(key) { NodeList.prototype.attr = function(key) {
this.item(0).attr(key) // CB TODO review this.item(0).attr(key);
} }
Element.prototype.data = function (key) { Element.prototype.data = function (key) {
return this.attributes[`data-${key}`].value return this.attributes[`data-${key}`].value
} }
NodeList.prototype.data = function(key) { NodeList.prototype.data = function(key) {
this.item(0).data(key) // CB TODO review this.item(0).data(key);
}
NodeList.prototype.show = function(key) {
this.item(0).show(key);
return this;
}
Element.prototype.show = function (key) {
this.style.display = 'block';
}
NodeList.prototype.hide = function(key) {
this.item(0).hide(key);
return this;
}
Element.prototype.hide = function (key) {
this.style.display = 'none';
} }
let initFunctions = []; let initFunctions = [];
function onLoad(fct) { function onLoad(fct) {

View File

@@ -83,3 +83,39 @@ function exportCSV(filename, content) {
link.click(); link.click();
document.body.removeChild(link); document.body.removeChild(link);
} }
/* modals */
NodeList.prototype.modal = function(show) {
this.item(0).modal(show);
return this;
}
Element.prototype.modal = function(show) {
if (show) {
document.body.addClass('dimmed');
this.addClass('active');
}
else {
this.removeClass('active');
document.body.removeClass('dimmed');
}
return this;
}
onLoad(() => {
/*
document.on('click', e => {
if (!e.target.closest('.modal')) $('.modal').hide();
})
*/
$('i.close.icon').on('click', e => {
let modal = e.target.closest('.modal');
if (modal) modal.modal(false);
});
$('.modal .actions .cancel').on('click', e => {
e.target.closest('.modal').modal(false);
});
$('#dimmer').on('click', e => $('.modal').modal(false));
});

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
.datepicker{width:-moz-min-content;width:min-content}.datepicker:not(.active){display:none}.datepicker-dropdown{padding-top:4px;position:absolute;z-index:20}.datepicker-dropdown.datepicker-orient-top{padding-bottom:4px;padding-top:0}.datepicker-picker{background-color:#fff;border-radius:4px;display:flex;flex-direction:column}.datepicker-dropdown .datepicker-picker{box-shadow:0 2px 3px hsla(0,0%,4%,.1),0 0 0 1px hsla(0,0%,4%,.1)}.datepicker-main{flex:auto;padding:2px}.datepicker-footer{background-color:#f5f5f5;box-shadow:inset 0 1px 1px hsla(0,0%,4%,.1)}.datepicker-title{background-color:#f5f5f5;box-shadow:inset 0 -1px 1px hsla(0,0%,4%,.1);font-weight:700;padding:.375rem .75rem;text-align:center}.datepicker-controls{display:flex}.datepicker-header .datepicker-controls{padding:2px 2px 0}.datepicker-controls .button{align-items:center;background-color:#fff;border:1px solid #dcdcdc;border-radius:4px;box-shadow:none;color:#363636;cursor:pointer;display:inline-flex;font-size:1rem;height:2.25em;justify-content:center;line-height:1.5;margin:0;padding:calc(.375em - 1px) .75em;position:relative;text-align:center;vertical-align:top;white-space:nowrap}.datepicker-controls .button:active,.datepicker-controls .button:focus{outline:none}.datepicker-controls .button:hover{border-color:#b8b8b8;color:#363636}.datepicker-controls .button:focus{border-color:#3273dc;color:#363636}.datepicker-controls .button:focus:not(:active){box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.datepicker-controls .button:active{border-color:#474747;color:#363636}.datepicker-controls .button[disabled]{cursor:not-allowed}.datepicker-header .datepicker-controls .button{border-color:transparent;font-weight:700}.datepicker-header .datepicker-controls .button:hover{background-color:#f9f9f9}.datepicker-header .datepicker-controls .button:active{background-color:#f2f2f2}.datepicker-footer .datepicker-controls .button{border-radius:2px;flex:auto;font-size:.75rem;margin:calc(.375rem - 1px) .375rem}.datepicker-controls .view-switch{flex:auto}.datepicker-controls .next-button,.datepicker-controls .prev-button{flex:0 0 14.2857142857%;padding-left:.375rem;padding-right:.375rem}.datepicker-controls .next-button.disabled,.datepicker-controls .prev-button.disabled{visibility:hidden}.datepicker-grid,.datepicker-view{display:flex}.datepicker-view{align-items:stretch;width:15.75rem}.datepicker-grid{flex:auto;flex-wrap:wrap}.datepicker .days{display:flex;flex:auto;flex-direction:column}.datepicker .days-of-week{display:flex}.datepicker .week-numbers{display:flex;flex:0 0 9.6774193548%;flex-direction:column}.datepicker .weeks{align-items:stretch;display:flex;flex:auto;flex-direction:column}.datepicker span{-webkit-touch-callout:none;align-items:center;border-radius:4px;cursor:default;display:flex;justify-content:center;-webkit-user-select:none;-moz-user-select:none;user-select:none}.datepicker .dow{font-size:.875rem;font-weight:700;height:1.5rem}.datepicker .week{color:#b8b8b8;flex:auto;font-size:.75rem}.datepicker .days .dow,.datepicker-cell{flex-basis:14.2857142857%}.datepicker-cell{height:2.25rem}.datepicker-cell:not(.day){flex-basis:25%;height:4.5rem}.datepicker-cell:not(.disabled):hover{background-color:#f9f9f9;cursor:pointer}.datepicker-cell.focused:not(.selected){background-color:#e9e9e9}.datepicker-cell.selected,.datepicker-cell.selected:hover{background-color:#3273dc;color:#fff;font-weight:600}.datepicker-cell.disabled{color:#dcdcdc}.datepicker-cell.next:not(.disabled),.datepicker-cell.prev:not(.disabled){color:#7a7a7a}.datepicker-cell.next.selected,.datepicker-cell.prev.selected{color:#e6e6e6}.datepicker-cell.highlighted:not(.selected):not(.range):not(.today){background-color:#f5f5f5;border-radius:0}.datepicker-cell.highlighted:not(.selected):not(.range):not(.today):not(.disabled):hover{background-color:#efefef}.datepicker-cell.highlighted:not(.selected):not(.range):not(.today).focused{background-color:#e9e9e9}.datepicker-cell.today:not(.selected){background-color:#00d1b2}.datepicker-cell.today:not(.selected):not(.disabled){color:#fff}.datepicker-cell.today.focused:not(.selected){background-color:#00ccad}.datepicker-cell.range-end:not(.selected),.datepicker-cell.range-start:not(.selected){background-color:#b8b8b8;color:#fff}.datepicker-cell.range-end.focused:not(.selected),.datepicker-cell.range-start.focused:not(.selected){background-color:#b3b3b3}.datepicker-cell.range-start:not(.range-end){border-radius:4px 0 0 4px}.datepicker-cell.range-end:not(.range-start){border-radius:0 4px 4px 0}.datepicker-cell.range{background-color:#dcdcdc;border-radius:0}.datepicker-cell.range:not(.disabled):not(.focused):not(.today):hover{background-color:#d7d7d7}.datepicker-cell.range.disabled{color:#c6c6c6}.datepicker-cell.range.focused{background-color:#d1d1d1}.datepicker-input.in-edit{border-color:#276bda}.datepicker-input.in-edit:active,.datepicker-input.in-edit:focus{box-shadow:0 0 .25em .25em rgba(39,107,218,.2)}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,2 @@
New locales for the datepicker can be downloaded from [the datepicker repository](https://github.com/mymth/vanillajs-datepicker/tree/master/dist/js/locales)

View File

@@ -0,0 +1,18 @@
/**
* British English translation for bootstrap-datepicker
* Xavier Dutreilh <xavier@dutreilh.com>
*/
(function () {
Datepicker.locales['en-GB'] = {
days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
today: "Today",
monthsTitle: "Months",
clear: "Clear",
weekStart: 1,
format: "dd/mm/yyyy"
};
}());

View File

@@ -0,0 +1,18 @@
/**
* French translation for bootstrap-datepicker
* Nico Mollet <nico.mollet@gmail.com>
*/
(function () {
Datepicker.locales.fr = {
days: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"],
daysShort: ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."],
daysMin: ["d", "l", "ma", "me", "j", "v", "s"],
months: ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"],
monthsShort: ["janv.", "févr.", "mars", "avril", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc."],
today: "Aujourd'hui",
monthsTitle: "Mois",
clear: "Effacer",
weekStart: 1,
format: "dd/mm/yyyy"
};
}());

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -0,0 +1,70 @@
<form id="new-tournament-form" class="ui form">
<div class="ui infos tab segment">
<div class="field">
<label>Tournament name</label>
<input type="text" name="name" placeholder="Tournament name"/>
</div>
<div class="field">
<label>Tournament short name</label>
<input type="text" name="shortname" placeholder="short_name"/>
</div>
<div class="field">
<label>Tournament dates</label>
<span id="date-range">from <input type="text" name="start" class="date" placeholder="start date"/> to <input type="text" name="end" class="date" placeholder="end date"/></span>
</div>
<div class="field">
<label>Number of rounds</label>
<span><input type="number" name="rounds" min="1"/> rounds</span>
</div>
</div>
<div class="ui type tab segment">
<div class="grouped unstackable fields">
<label>Tournament type</label>
<div class="field">
<div class="ui radio">
<label>
<input type="radio" name="type" value="standard"/>
Standard tournament of individual players
</label>
</div>
</div>
<div class="field">
<div class="ui radio">
<label>
<input type="radio" name="type" value="partners"/>
<span>Partner teams tournament of <input type="number" min="2" name="partners"/> players</span> (pairgo / rengo)
</label>
</div>
</div>
<div class="field">
<div class="ui radio">
<label>
<input type="radio" name="type" value="teams"/>
<span>Teams tournament of <input type="number" min="2" name="partners"/> players</span> (teams of individual players)
</label>
</div>
</div>
</div>
</div>
<div class="ui pairing tab segment">
<div class="grouped unstackable fields">
<label>Tournament pairing</label>
<div class="field">
<div class="ui radio">
<label>
<input type="radio" name="pairing" value="macmahon"/>
MacMahon
</label>
</div>
</div>
<div class="field">
<div class="ui radio">
<label>
<input type="radio" name="pairing" value="swiss"/>
Swiss
</label>
</div>
</div>
</div>
</div>
</form>