diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..edd83c0 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +node_modules +npm-debug.log +Dockerfile +.dockerignore \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index d558314..942482f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,10 +4,21 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { + "name": "Attach", + "port": 9229, + "request": "attach", + "skipFiles": [ + "/**" + ], + "type": "node", + "localRoot": "${workspaceFolder}/src", + "remoteRoot": "/home/node/app/src" + }, { "console": "integratedTerminal", "internalConsoleOptions": "neverOpen", - "name": "nodemon", + "name": "nodemon (dev)", "program": "dev", "request": "launch", "restart": true, @@ -16,8 +27,8 @@ "/**" ], "type": "node", - "env": {"NODE_ENV": "development"}, - "preLaunchTask": "npm: scss" - } + "env": {"NODE_ENV": "development", "DEBUG": "app"}, + "preLaunchTask": "npm: build-css" + } ] } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 51203ad..5ba5947 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -3,17 +3,21 @@ "tasks": [ { "type": "npm", - "script": "scss", + "script": "watch-scss", "problemMatcher": [], - "label": "npm: scss watch", - "detail": "sass --watch src/scss/application.scss public/css/application.css src/scss/eventsheet.scss:public/css/eventsheet.css" + "label": "npm: watch-scss", + "detail": "npm run watch-css", + "icon": { + "id": "eye", + "color": "terminal.ansiBlue" + } }, { "type": "npm", - "script": "scss", + "script": "build-css", "problemMatcher": [], - "label": "npm: scss", - "detail": "sass src/scss/application.scss:public/css/application.css src/scss/eventsheet.scss:public/css/eventsheet.css" + "label": "npm: build-css", + "detail": "npm build-css" } ] } \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e8caf97 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM node:21 + +RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app +RUN mkdir -p /home/node/app/var/db && chown -R node:node /home/node/app +WORKDIR /home/node/app + +USER node +COPY --chown=node:node package*.json ./ +RUN npm install +COPY --chown=node:node src src +COPY --chown=node:node bin bin + +EXPOSE 3000 +CMD [ "npm", "start" ] diff --git a/bin/www b/bin/www index 36e14e1..c606d7f 100755 --- a/bin/www +++ b/bin/www @@ -10,8 +10,7 @@ var https = require("https"); var fs = require("fs"); var debug = require("debug")("https"); const path = require("path"); - - +var livereload = require("livereload"); /** * Get port from environment and store in Express. @@ -19,32 +18,18 @@ const path = require("path"); var port = normalizePort(process.env.PORT || "3000"); app.set("port", port); - -/** - * Create HTTPS server. - */ -const https_options = { - key: fs.readFileSync("certs/key.pem"), - cert: fs.readFileSync("certs/cert.pem"), -}; +var server = http.createServer(app); if (process.env.NODE_ENV === "development") { - // console.log(`starting livereload, watching ${path.join(__dirname, "../src/views")}`) - var livereload = require("livereload"); - var connectLiveReload = require("connect-livereload"); - - const liveReloadServer = livereload.createServer({https: https_options, extraExts: ['pug']}); + const liveReloadServer = livereload.createServer({port:35729}); liveReloadServer.watch(path.join(__dirname, "../src/views")); liveReloadServer.server.once("connection", () => { setTimeout(() => { liveReloadServer.refresh("/"); }, 100); }); - } -var server = https.createServer(https_options, app); - /** * Listen on provided port, on all network interfaces. */ diff --git a/caddy/Caddyfile b/caddy/Caddyfile new file mode 100644 index 0000000..9980f1f --- /dev/null +++ b/caddy/Caddyfile @@ -0,0 +1,26 @@ +{ + {$LOG_LEVEL} # Set via environment variable +} + +localhost { + # Development configuration + @notProd { + expression {env.ENVIRONMENT} == 'development' + } + handle @notProd { + # Configuration that only applies when not in production + reverse_proxy app-dev:3000 + } +} + +{$DOMAIN} { + # Production configuration + @prod { + expression {env.ENVIRONMENT} == 'production' + } + handle @prod { + # Configuration that only applies in production + # header Strict-Transport-Security "max-age=31536000;" + reverse_proxy app:3000 + } +} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..ff9c57a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,50 @@ +services: + app: &app + env_file: + - .env + build: . + networks: + - web + profiles: + - production + expose: + - 3000 + + app-dev: + <<: *app + ports: + - 9229:9229 #debugger + - 35729:35729 #livereload + profiles: + - development + command: npm run dev + volumes: + - ./src:/home/node/app/src + - ./package.json:/home/node/app/package.json + - ./package-lock.json:/home/node/app/package-lock.json + - ./certs:/home/node/app/certs + - ./bin/www:/home/node/app/bin/www + environment: + DEBUG: "app" + NODE_ENV: "development" + + caddy: + image: caddy + ports: + - 80:80 + - 443:443 + volumes: + - ./caddy/Caddyfile:/etc/caddy/Caddyfile + - caddy_data:/data + - caddy_config:/config + networks: + - web + env_file: + - .env + +networks: + web: + +volumes: + caddy_data: + caddy_config: \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 0f44e2c..d7dc921 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "passport-teamsnap": "^1.1.1", "pluralize": "^8.0.0", "pug": "^3.0.2", + "sass": "^1.77.2", "sortablejs": "^1.15.0", "teamsnap.js": "github:anthonyscorrea/teamsnap-javascript-sdk#link-with-null-link", "tinymce": "^6.8.3", @@ -663,7 +664,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -834,7 +834,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, "engines": { "node": ">=8" } @@ -997,7 +996,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -1169,7 +1167,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -2040,7 +2037,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2195,7 +2191,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -2304,7 +2299,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -2564,6 +2558,11 @@ "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", "dev": true }, + "node_modules/immutable": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz", + "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==" + }, "node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", @@ -2632,7 +2631,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -2704,7 +2702,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -2722,7 +2719,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -2745,7 +2741,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { "node": ">=0.12.0" } @@ -3373,7 +3368,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3667,7 +3661,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -4078,7 +4071,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -4228,6 +4220,22 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/sass": { + "version": "1.77.2", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.2.tgz", + "integrity": "sha512-eb4GZt1C3avsX3heBNlrc7I09nyT00IUuo4eFhAbeXWU2fvA7oXI53SxODVAA+zgZCk9aunAZgO+losjR3fAwA==", + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/semver": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", @@ -4466,6 +4474,14 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -4735,7 +4751,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "dependencies": { "is-number": "^7.0.0" }, diff --git a/package.json b/package.json index 66ef4a6..cbd6151 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,13 @@ }, "scripts": { "start": "node ./bin/www", - "dev": "nodemon . & npm run scss", - "scss": "sass src/scss/application.scss:src/public/css/application.css src/scss/eventsheet.scss:src/public/css/eventsheet.css", - "scss watch": "sass --watch src/scss/application.scss:src/public/css/application.css src/scss/eventsheet.scss:src/public/css/eventsheet.css" + "dev": "nodemon --inspect=0.0.0.0 ./bin/www", + "build-css": "sass src/scss:src/public/css", + "watch-scss": "nodemon -e scss -x \"npm run build-css\"" + }, + "nodemonConfig": { + "ext": "js,hbs,scss", + "watch": ["src"] }, "dependencies": { "@teamsnap/teamsnap-ui": "^3.12.3", @@ -54,6 +58,7 @@ "passport-teamsnap": "^1.1.1", "pluralize": "^8.0.0", "pug": "^3.0.2", + "sass": "^1.77.2", "sortablejs": "^1.15.0", "teamsnap.js": "github:anthonyscorrea/teamsnap-javascript-sdk#link-with-null-link", "tinymce": "^6.8.3", diff --git a/src/app.js b/src/app.js index 9aef7b1..09c6f13 100644 --- a/src/app.js +++ b/src/app.js @@ -62,12 +62,14 @@ app.set("view engine", "hbs"); app.locals.pluralize = require("pluralize"); if (process.env.NODE_ENV === "development") { + console.log('adding connectLiveReload') var connectLiveReload = require("connect-livereload"); - app.use(connectLiveReload()); + app.use("/scss", express.static(path.join(__dirname, "scss"))); + app.use(connectLiveReload({port: 35729, src:"http://localhost:35729/livereload.js?snipver=1"})); } app.use(bodyParser.json()); -app.use(bodyParser.urlencoded()); +app.use(bodyParser.urlencoded({extended: true })); app.use(logger("dev")); app.use(cors(corsOptions)) app.use(cookieParser()); @@ -172,7 +174,10 @@ app.use(function (err, req, res, next) { // catch 404 and forward to error handler app.use(function (req, res, next) { - next(createError(404)); + // next(createError(404)); + res.status(404).send('not found') }); +app.set('trust proxy') + module.exports = {app}; \ No newline at end of file diff --git a/src/controllers/eventlineup.js b/src/controllers/eventlineup.js index 31f1eb3..3fbf38b 100644 --- a/src/controllers/eventlineup.js +++ b/src/controllers/eventlineup.js @@ -1,6 +1,6 @@ const path = require('path') const fs = require('fs') -const {embeddedSvgFromPath, parsePositionLabel, compilePositionLabel} = require("../lib/utils") +const {groupTeamsnapItems, parsePositionLabel, compilePositionLabel, teamsnapCallback} = require("../lib/utils") const tsUtils = require('../lib/utils') const { loadEventLineupEntries } = require('teamsnap.js') @@ -38,14 +38,14 @@ exports.getAdjacentEventLineup = async (req, res) => { return } const availabilitySummary = event.availabilitySummary - const event_lineup = req.timeline.event_lineups.find(i=>i.eventId==event.id) + const event_lineup = req.timeline.event_lineups?.find(i=>i.eventId==event.id) const event_lineup_entries = req.timeline.event_lineup_entries?.filter(i=>i.eventId==event.id) const availabilities = req.timeline.availabilities.filter(i=>i.eventId==event.id) attachBenchcoachPropertiesToMember(members, event_lineup_entries, availabilities) members.sort(tsUtils.teamsnapMembersSortLineupAvailabilityLastName) console.log() - // res.status(200).send('Received') - res.render("eventlineup/edit", {user, team, members, event, layout: null, event_lineup, event_lineup_entries, availabilitySummary, csrfToken}) + + res.render("eventlineup/edit", {user, team, members, event, layout: null, event_lineup, event_lineup_entries, availabilitySummary, availabilities, csrfToken}) } attachBenchcoachPropertiesToMember = (members, event_lineup_entries, availabilities) => { @@ -109,14 +109,20 @@ exports.postEventLineup = async (req,res) => { const eventLineupEntries = req.event_lineup.eventLineupEntries const {newEventLineupEntries, deleteEventLineupEntries} = processPostedEventLineupEntries(body, eventLineupEntries, req.event_lineup) newEventLineupEntries.forEach(e=>{ - teamsnap.saveEventLineupEntry(e) + teamsnap.saveEventLineupEntry(e, teamsnapCallback) }) deleteEventLineupEntries.forEach(e=>{ - teamsnap.deleteEventLineupEntry(e) + teamsnap.deleteEventLineupEntry(e, teamsnapCallback) }) - eventLineup = await teamsnap.loadEventLineups(req.params.event_id) - res.status(201).end() + const bulk_items = await teamsnap.bulkLoad( + {teamId: req.params.team_id, types: ['eventLineup', 'eventLineupEntry'], scopeTo:'event', event__id:req.params.event_id,}, + null, + (err, items) => {teamsnapCallback(err, items, {req, source:"postEventLineup", method:'bulkLoad'})} + ) + groupedReturnedItems = groupTeamsnapItems(bulk_items) + returnedEventLineupEntries = groupedReturnedItems.eventLineupEntries + res.status(201).end(JSON.stringify(returnedEventLineupEntries)) } const processPostedEventLineupEntries = (body, eventLineupEntries, eventLineup) => { diff --git a/src/controllers/eventsheet.js b/src/controllers/eventsheet.js index 3649901..efc152f 100644 --- a/src/controllers/eventsheet.js +++ b/src/controllers/eventsheet.js @@ -23,8 +23,14 @@ exports.getEventSheet = async (req,res) =>{ ) ) await Promise.all(req.promises) + const {sheet_size, sheet_layout} = req.query + const {user, team, team_preferences, members, event, event_lineup, event_lineup_entries, availabilities, availabilitySummary, timeline, recent_events, opponent_logo, upcoming_events} = req - res.render('eventsheet/sheet', {user, team, team_preferences, members, event, event_lineup, event_lineup_entries, availabilities, availabilitySummary, timeline, recent_events, opponent_logo,upcoming_events}) + res.render('eventsheet/sheet', {sheet_size, sheet_layout, user, team, team_preferences, members, event, event_lineup, event_lineup_entries, availabilities, availabilitySummary, timeline, recent_events, opponent_logo,upcoming_events}) +} + +exports.getEventSheetBlank = (req,res) => { + res.render('eventsheet/sheet_blank') } exports.getLineupCard = (req, res, next) => { diff --git a/src/helpers/eventlineup.js b/src/helpers/eventlineup.js index aabb973..94cc85a 100644 --- a/src/helpers/eventlineup.js +++ b/src/helpers/eventlineup.js @@ -95,7 +95,7 @@ exports.loadSlots = (options) =>{ var s = "" const {members, event_lineup, event_lineup_entries, event, availabilities} = options.data.root event_lineup_entries.forEach(eventLineupEntry =>{ - const availability = availabilities.find(a=>a.memberId==eventLineupEntry.memberId) + const availability = availabilities?.find(a=>a.memberId==eventLineupEntry.memberId) const member = members.find(m=>m.id==eventLineupEntry.memberId) const {positionFlags} = parsePositionLabel(eventLineupEntry.label) const initial_slotset = `lineup-${positionFlags.has('PO') ? 'positiononly' : 'starting'}-${event.id}` @@ -106,9 +106,9 @@ exports.loadSlots = (options) =>{ member=>!event_lineup_entries.map(lue=>lue.memberId).includes(member.id) && !member.isNonPlayer ) players_without_lineup_entry.forEach(member =>{ - const availability = availabilities.find(a=>a.memberId==member.id) + const availability = availabilities?.find(a=>a.memberId==member.id) let initial_slotset - if (availability.statusCode == 0 || availability.statusCode == null) { + if (availability?.statusCode == 0 || availability?.statusCode == null) { initial_slotset =`lineup-out-${event.id}` } else { initial_slotset =`lineup-bench-${event.id}` diff --git a/src/helpers/eventsheet.js b/src/helpers/eventsheet.js index 2222bb4..73574d4 100644 --- a/src/helpers/eventsheet.js +++ b/src/helpers/eventsheet.js @@ -1,5 +1,6 @@ const { parsePositionLabel, teamsnapMembersSortLineupAvailabilityLastName, teamsnapMembersSortAvailabilityLastName } = require('../lib/utils') const {attachBenchcoachPropertiesToMember} = require('../controllers/eventlineup') +const Handlebars = require("handlebars"); exports.offenseLineup = (number_of_slots, event_lineup_entries, members, options) => { var results = "" @@ -60,7 +61,7 @@ exports.rosterHistory = (event, event_lineup_entries, members, availabilities, o // const {event, event_lineup_entries, members, availabilities} = options.data.root const players = members.filter(m=>!m.isNonPlayer) attachBenchcoachPropertiesToMember(players, event_lineup_entries ? event_lineup_entries.filter(i=>i.eventId==event.id) : [], availabilities.filter(i=>i.eventId==event.id)) - players.sort(teamsnapMembersSortAvailabilityLastName) + players.sort(teamsnapMembersSortLineupAvailabilityLastName) players.forEach(member=>{ const {firstName, lastName, jerseyNumber, benchcoach, position, id} = member @@ -112,8 +113,15 @@ exports.repeat = (n, options) => { exports.loopEvents = (events, options) => { var results = ""; - events.forEach(event => { - results += options.fn(event) + if (options.data) { + data = Handlebars.createFrame(options.data); + } + + events.forEach((event,i) => { + if (data) { + data.index = i; + } + results += options.fn(event, {data: data }) } ) return results; @@ -121,6 +129,9 @@ exports.loopEvents = (events, options) => { exports.timepointForMember = (member, timeline, event, options) => { var results = "" + if (options.data) { + data = Handlebars.createFrame(options.data); + } const availability = timeline.availabilities.find(a=>a.memberId==member.id && a.eventId==event.id) const eventLineupEntry = timeline.event_lineup_entries.find(a=>(a.memberId==member.id || a.memberName == `${member.firstName} ${member.lastName}`) && a.eventId==event.id) var value = "" @@ -130,5 +141,13 @@ exports.timepointForMember = (member, timeline, event, options) => { else { value = availability.status[0] } - return options.fn({availability: availability, eventLineupEntry: eventLineupEntry, value}) + return options.fn({availability: availability, eventLineupEntry: eventLineupEntry, value}, {data: data }) +} + +exports.ifEquals = (testValue, targetValue, options) => { + if (testValue === targetValue) { + return options.fn(); + } else { + return ''; + } } \ No newline at end of file diff --git a/src/public/css/eventsheet.css b/src/public/css/eventsheet.css index 75dc6c0..a724e6f 100644 --- a/src/public/css/eventsheet.css +++ b/src/public/css/eventsheet.css @@ -4,56 +4,7 @@ @import url("https://fonts.googleapis.com/css2?family=Graduate"); @import url("https://fonts.googleapis.com/css2?family=Inconsolata:wdth,wght@50..200,200..900&display=swap"); @import url("/font/helvetica-now/stylesheet.css"); -@font-face { - font-family: "Futura Now"; - src: url("/font/futura-now/futura-now.ttf") format("truetype"); - font-weight: 125 900; - font-stretch: 50% 150%; -} -@page { - margin: 0; -} -/** For Print **/ -@media print { - body { - margin: 0; - } - body .sheet { - size: B5; - padding: 0.175in; - } -} -/** For screen preview **/ -@media screen { - body .sheet { - padding: 0.175in; - } - body { - background: #e0e0e0; - } - .sheet { - background: white; - box-shadow: 0 0.5mm 2mm rgba(0, 0, 0, 0.3); - } -} -.sheet { - overflow: hidden; - position: relative; - box-sizing: border-box; - page-break-after: always; -} - -/** Paper sizes **/ -body.B5 .sheet { - width: 176mm; - height: 250mm; -} - -body.index-card .sheet { - width: 3.5in; - height: 5in; -} - +@import url("/font/futura-now/stylesheet.css"); :root { --color-success: #b7e1cd; --color-danger: #f4c7c3; @@ -68,18 +19,71 @@ body.index-card .sheet { --color-grey-700: #495057; --color-grey-800: #343a40; --color-grey-900: #212529; + --header-height: 17px; --row-height: 14px; --monospace-font: "Inconsolata", monospace; + --section-border: 0.5px solid black; +} + +/** For Print **/ +@media print { + :root { + margin: 0; + } + body { + margin: 0; + } + body .sheet { + padding: 0.175in; + background: white; + } +} +/** For screen preview **/ +@media screen { + body .sheet { + padding: 0.175in; + } + body { + background: #e0e0e0; + } + .sheet { + margin: auto; + margin-bottom: 12px; + box-shadow: 0 0.5mm 2mm rgba(0, 0, 0, 0.3); + } +} +.sheet { + overflow: hidden; + position: relative; + box-sizing: border-box; + page-break-after: always; + background: white; +} + +/** Paper sizes **/ +body.B5 .sheet { + width: 176mm; + height: 250mm; +} + +body.index-card .sheet { + width: 3.5in; + height: 5in; +} + +body.letter .sheet { + width: 8.5in; + height: 11in; } body { font-family: "Helvetica Now", "Helvetica", sans-serif; position: relative; font-size: 11px; + text-transform: uppercase; } -table { - position: inherit; +table, #roster-and-history table, .lineup-card table { font-size: inherit; border-collapse: collapse; empty-cells: show; @@ -88,45 +92,23 @@ table { overflow-x: hidden; overflow-y: hidden; width: 100%; - border: 0.5px solid black; - display: inline-table; } -table tr { - border-bottom-width: 0.5px; - border-color: grey; - border-bottom-style: solid; +table th, #roster-and-history table th, .lineup-card table th { + color: var(--color-grey-700); } -table tr:nth-child(odd) { - background-color: rgba(242, 242, 242, 0.85); -} -table tr:nth-child(even) { - background-color: rgba(255, 255, 255, 0.85); -} -table tr th { - font-stretch: extra-condensed; - width: 1em; - text-align: center; - text-transform: uppercase; -} -table tr td.player-name { - text-transform: uppercase; - font-stretch: 75%; -} -table tr td.position, table tr td.jersey-number { - font-family: var(--monospace-font); - width: 2ch; - text-align: right; - overflow: hidden; -} -table tr th, table tr td { - border-left: 0.5px solid grey; - border-right: 0.5px solid grey; +table th, #roster-and-history table th, .lineup-card table th, table td, table #roster-and-history .position, #roster-and-history table .position, #roster-and-history table td, .lineup-card table td { overflow: hidden; padding: 0 2px 0 2px; } -table tr th:empty::after, table tr td:empty::after { +table th:empty::after, #roster-and-history table th:empty::after, table td:empty::after, table #roster-and-history .position:empty::after, #roster-and-history table .position:empty::after, #roster-and-history table td:empty::after { content: " "; } +table.striped tr:nth-child(odd) td, table.striped tr:nth-child(odd) #roster-and-history .position, #roster-and-history table tr:nth-child(odd) td, #roster-and-history table tr:nth-child(odd) .position, .lineup-card table tr:nth-child(odd) td, .lineup-card table tr:nth-child(odd) #roster-and-history .position, table.striped tr:nth-child(odd) th, #roster-and-history table tr:nth-child(odd) th, .lineup-card table tr:nth-child(odd) th { + background-color: whitesmoke; +} +table.striped tr:nth-child(even) td, table.striped tr:nth-child(even) #roster-and-history .position, #roster-and-history table tr:nth-child(even) td, #roster-and-history table tr:nth-child(even) .position, .lineup-card table tr:nth-child(even) td, .lineup-card table tr:nth-child(even) #roster-and-history .position, table.striped tr:nth-child(even) th, #roster-and-history table tr:nth-child(even) th, .lineup-card table tr:nth-child(even) th { + background-color: white; +} .float-right { float: right; @@ -136,203 +118,173 @@ table tr th:empty::after, table tr td:empty::after { float: left; } -.B5 > .eventsheet { - display: grid; - grid-template-columns: 1fr 1fr; - grid-template-rows: 1fr 1fr; - column-gap: 0.35in; - row-gap: 0.35in; - background-size: 100%; +.eventsheet { + --page-margin: 0.175in; } - -.eventsheet > section { +.eventsheet:has(section) { + display: grid; +} +.eventsheet:has(section) section { + --divider-border: lightgrey dashed 1px; box-sizing: content-box; overflow: hidden; - /* outline: 0.5px dashed lightgrey; */ display: flex; flex-direction: column; align-items: stretch; + outline-style: solid; + outline-width: calc(var(--divider-border) / 4); + outline-color: lightgray; } -.eventsheet > section > div { +.eventsheet:has(section) section > div { display: flex; flex: 1; align-items: stretch; height: auto; -} -.eventsheet > section.NW { - grid-area: 1/1/2/2; -} -.eventsheet > section.NE { - grid-area: 1/2/2/3; -} -.eventsheet > section.SW { - grid-area: 2/1/3/2; -} -.eventsheet > section.SE { - grid-area: 2/2/3/3; -} - -.eventsheet > .section-divider { - position: absolute; - display: grid; - grid-template-columns: repeat(2, 1fr); - grid-template-rows: repeat(2, 1fr); - grid-column-gap: 0px; - grid-row-gap: 0px; - height: 100%; width: 100%; - box-sizing: border-box; - --divider-border: lightgrey dashed 1px; } -.eventsheet > .section-divider .NW { +.eventsheet:has(section) section.NW { grid-area: 1/1/2/2; - border-right: var(--divider-border); - border-bottom: var(--divider-border); } -.eventsheet > .section-divider .NE { +.eventsheet:has(section) section.NE { grid-area: 1/2/2/3; - border-bottom: var(--divider-border); } -.eventsheet > .section-divider .SW { +.eventsheet:has(section) section.SW { grid-area: 2/1/3/2; - border-right: var(--divider-border); } -.eventsheet > .section-divider .SE { +.eventsheet:has(section) section.SE { grid-area: 2/2/3/3; } +.eventsheet:has(section) section.NW .divider, .eventsheet:has(section) section.SW .divider { + border-right: var(--divider-border); +} +.eventsheet:has(section) section.NW .divider, .eventsheet:has(section) section.NE .divider { + border-bottom: var(--divider-border); +} +.eventsheet.quarters { + --section-margin: calc(var(--page-margin)/2); + grid-template-columns: 1fr 1fr; + grid-template-rows: 1fr 1fr; + column-gap: calc(var(--page-margin) * 2); + row-gap: calc(var(--page-margin) * 2); + outline-offset: var(--section-margin); +} +.eventsheet.quarters section { + outline-offset: var(--page-margin); +} + +.letter .eventsheet.quarters { + --header-height: 0.5in; +} + +.letter .eventsheet.index-cards-4x6 { + --section-margin: calc(var(--page-margin)/2); + grid-template-columns: 1fr 1fr; + grid-template-rows: 1fr 125mm; + column-gap: calc(var(--page-margin) * 2); + row-gap: calc(var(--page-margin) * 2); +} +.letter .eventsheet.index-cards-4x6 section { + outline-offset: var(--page-margin); +} + +.letter .eventsheet.index-cards-3x5 { + --section-margin: calc(var(--page-margin)/2); + grid-template-columns: 3in 3in; + grid-template-rows: 5in 5in; + column-gap: calc(var(--page-margin) * 2); + row-gap: calc(var(--page-margin) * 2); +} +.letter .eventsheet.index-cards-3x5 section { + outline-offset: var(--page-margin); +} + +.lineup-card { + counter-reset: lineup-sequence-counter 0; + --border: 0.5px solid grey; + border: var(--section-border); +} +.lineup-card header { + text-transform: uppercase; + border-style: none; + border-bottom: var(--border); + height: var(--header-height); +} +.lineup-card header:empty::after { + content: " "; +} .lineup-card th { width: inherit; } - -#lineup-card-dugout div.grid-container, -#lineup-card-dugout-blank div.grid-container { - display: grid; - grid-template-columns: 60% auto; - grid-template-rows: fit-content(16px) auto; - grid-template-areas: "header header" "sarting-lineup-table substitution-table"; -} - -#lineup-card-exchange div.grid-container, -#lineup-card-exchange-blank div.grid-container { - display: grid; - grid-template-columns: auto; - grid-template-rows: fit-content(16px) auto; - grid-template-areas: "header" "sarting-lineup-table"; -} - -#lineup-card-exchange .substitution, -#lineup-card-exchange .homeaway, -#lineup-card-exchange-blank .substitution, -#lineup-card-exchange-blank .homeaway { - display: none; -} - -.lineup-card div.grid-container > header { - grid-area: "header"; - font-size: 14px; - font-weight: bold; -} - -.lineup-card div.grid-container > header:empty::after { - content: " "; -} - -div.grid-container > .starting-lineup-table { - grid-area: "starting-lineup-table"; -} - -div.grid-container > .substitution-table { - grid-area: "substitution-table"; -} - -section.lineup-card { - counter-reset: lineup-sequence-counter 0; -} -section.lineup-card thead th { - color: var(--color-grey-600); - font-size: 0.7em; -} -section.lineup-card th.sequence { +.lineup-card th.sequence { counter-increment: lineup-sequence-counter 1; color: var(--color-grey-600); font-size: inherit; width: 2ch; + font-stretch: 50%; + border-right: var(--border); } -section.lineup-card th.sequence.counter::before { +.lineup-card th.sequence.counter::before { content: counter(lineup-sequence-counter); } - -.lineup-card table { +.lineup-card thead th { + color: var(--color-grey-600); + font-size: 0.7em; + border-bottom: var(--border); +} +.lineup-card table, .lineup-card #roster-and-history table, #roster-and-history .lineup-card table { font-size: 21px; } - -.lineup-card td { +.lineup-card td, .lineup-card #roster-and-history .position, #roster-and-history .lineup-card .position { /* height: 34px; */ } - -.lineup-card td.substitution { +.lineup-card td.substitution, .lineup-card #roster-and-history .substitution.position, #roster-and-history .lineup-card .substitution.position { width: 8ch; } - -.lineup-card td.substitution::after { +.lineup-card td.substitution::after, .lineup-card #roster-and-history .substitution.position::after, #roster-and-history .lineup-card .substitution.position::after { content: ""; } - -#lineup-card-exchange tr, -#lineup-card-exchange-blank tr, -#lineup-card-dugout .starting-lineup-table tr, -#lineup-card-dugout-blank .starting-lineup-table tr, -#lineup-card-dugout .substitution-table tr:nth-child(odd) { - border-top: 1px solid black; -} - -#lineup-card-exchange tr, -#lineup-card-exchange-blank tr, -#lineup-card-dugout .starting-lineup-table tr, -#lineup-card-dugout-blank .starting-lineup-table tr, -#lineup-card-dugout .substitution-table tr:nth-child(even) { - border-bottom: 1px solid black; -} - -td.substitution { - border-left: 1px solid black; -} - -section.blank { - filter: opacity(0.4); -} -section.blank img, section.blank header { - filter: grayscale(1); -} -section.blank td.substitution { - border-width: 0.5; -} - -#lineup-card-exchange td.player-name { - font-stretch: 100%; -} - -#lineup-card-dugout td.player-name { - width: 10ch; -} - -.lineup-card .position, -.lineup-card .jersey-number { +.lineup-card td.position, .lineup-card #roster-and-history .position, #roster-and-history .lineup-card .position, .lineup-card td.jersey-number { width: 2ch; } - -#lineup-card-dugout .position, -#lineup-card-dugout .jersey-number { - font-stretch: 75%; +.lineup-card td.position, .lineup-card #roster-and-history .position, #roster-and-history .lineup-card .position, .lineup-card td.jersey-number, .lineup-card td.substitution { + font-family: var(--monospace-font); + border-left: var(--border); + text-align: right; padding-left: 2.5px; padding-right: 2.5px; } +.lineup-card tr + tr td, .lineup-card tr + tr #roster-and-history .position, #roster-and-history .lineup-card tr + tr .position, .lineup-card tr + tr th { + border-top: var(--border); +} +.lineup-card.dugout td.player-name, .lineup-card.dugout #roster-and-history .player-name.position, #roster-and-history .lineup-card.dugout .player-name.position { + width: 10ch; + font-stretch: 75%; +} +.lineup-card.dugout .position, .lineup-card.dugout .jersey-number, .lineup-card.dugout .substitution { + font-stretch: 75%; +} +.lineup-card.exchange header { + text-align: center; +} +.lineup-card.exchange header .float-left, .lineup-card.exchange header .float-right { + float: none; +} +.lineup-card.exchange .player-name { + font-stretch: 100%; +} +.lineup-card.exchange .homeaway, .lineup-card.exchange .substitution { + display: none; +} -.lineup-card header { - font-size: inherit; - text-transform: uppercase; - font-stretch: 85%; +section.blank svg, section.blank header { + filter: grayscale(1) opacity(0.4); +} +section.blank > div { + filter: opacity(0.4); +} +section.blank > div td.substitution, section.blank > div #roster-and-history .substitution.position, #roster-and-history section.blank > div .substitution.position { + border-width: 0.5; } #todays-game > div { @@ -362,12 +314,12 @@ section.blank td.substitution { outline: none; border-style: none; } -#todays-game .footer table tr { +#todays-game .footer table tr td, #todays-game .footer table tr #roster-and-history .position, #roster-and-history #todays-game .footer table tr .position, #todays-game .footer table tr th { background-color: white; outline: none; border-bottom: 0.5px solid var(--color-grey-500); } -#todays-game .footer table tr :last-child { +#todays-game .footer table tr :last-child td, #todays-game .footer table tr :last-child #roster-and-history .position, #roster-and-history #todays-game .footer table tr :last-child .position { background-color: white; outline: none; border-bottom-style: none; @@ -376,7 +328,7 @@ section.blank td.substitution { text-align: left; color: var(--color-grey-600); } -#todays-game .footer table td { +#todays-game .footer table td, #todays-game .footer table #roster-and-history .position, #roster-and-history #todays-game .footer table .position { height: var(--row-height); border: none; } @@ -388,7 +340,7 @@ section.blank td.substitution { border-right: none; line-height: 1em; } -#todays-game table.notes td:empty::after { +#todays-game table.notes td:empty::after, #todays-game table.notes #roster-and-history .position:empty::after, #roster-and-history #todays-game table.notes .position:empty::after { content: ""; } @@ -418,12 +370,15 @@ section.blank td.substitution { display: table-row; } +#defense-card { + border: var(--section-border); +} + #defense-pane { position: relative; grid-area: defense; padding: 4px 4px 0px 4px; /* top right bottom left */ display: flex; - border: 0.5px solid grey; } #defense-pane .field-container { display: grid; @@ -433,38 +388,98 @@ section.blank td.substitution { width: 100%; z-index: 2; } -#defense-pane img { +#defense-pane svg { position: absolute; + stroke-linecap: round; + stroke-miterlimit: 1.5; z-index: -1; + opacity: 70%; +} +#defense-pane svg #outfield-path { + stroke: #4AA1D5; + fill: none; + stroke-width: 4px; +} +#defense-pane svg #infield-path { + stroke: #4AA1D5; + fill: #D1E6F7; + stroke-width: 4px; + fill-opacity: 50%; } #defense-pane .slot-set { display: flex; align-items: center; } +#defense-pane .slot-set .player-name { + font-stretch: 80%; +} +#defense-pane .slot-set table { + --border: grey solid 0.5px; + border: var(--border); + opacity: 85%; +} +#defense-pane .slot-set table tr:first-child th { + border-bottom: var(--border); +} +#defense-pane .slot-set table tr + tr td, #defense-pane .slot-set table tr + tr #roster-and-history .position, #roster-and-history #defense-pane .slot-set table tr + tr .position, #defense-pane .slot-set table tr + tr th { + border-top: var(--border); +} +#defense-pane .slot-set table tr th.position { + font-family: var(--monospace-font); + width: 2ch; + text-align: right; +} +#defense-pane .slot-set.pos-cf tr:first-child th.position:empty { + border-right: var(--border); +} #defense-pane .slot-set.pos-cf tr:first-child th.position:empty::after { content: "cf"; } +#defense-pane .slot-set.pos-lf tr:first-child th.position:empty { + border-right: var(--border); +} #defense-pane .slot-set.pos-lf tr:first-child th.position:empty::after { content: "lf"; } +#defense-pane .slot-set.pos-rf tr:first-child th.position:empty { + border-right: var(--border); +} #defense-pane .slot-set.pos-rf tr:first-child th.position:empty::after { content: "rf"; } +#defense-pane .slot-set.pos-ss tr:first-child th.position:empty { + border-right: var(--border); +} #defense-pane .slot-set.pos-ss tr:first-child th.position:empty::after { content: "ss"; } +#defense-pane .slot-set.pos-2b tr:first-child th.position:empty { + border-right: var(--border); +} #defense-pane .slot-set.pos-2b tr:first-child th.position:empty::after { content: "2b"; } +#defense-pane .slot-set.pos-3b tr:first-child th.position:empty { + border-right: var(--border); +} #defense-pane .slot-set.pos-3b tr:first-child th.position:empty::after { content: "3b"; } +#defense-pane .slot-set.pos-1b tr:first-child th.position:empty { + border-right: var(--border); +} #defense-pane .slot-set.pos-1b tr:first-child th.position:empty::after { content: "1b"; } +#defense-pane .slot-set.pos-c tr:first-child th.position:empty { + border-right: var(--border); +} #defense-pane .slot-set.pos-c tr:first-child th.position:empty::after { content: "c"; } +#defense-pane .slot-set.pos-p tr:first-child th.position:empty { + border-right: var(--border); +} #defense-pane .slot-set.pos-p tr:first-child th.position:empty::after { content: "p"; } @@ -508,6 +523,9 @@ section.blank td.substitution { #defense-pane .slot-set.pos-p table { width: 100%; } +#defense-pane .slot-set.pos-p tr.substitute .position:empty { + border-right: var(--border); +} #defense-pane .slot-set.pos-p tr.substitute .position:empty::after { content: "RP"; } @@ -531,40 +549,14 @@ section.blank td.substitution { content: counter(lineup-sequence-counter); } -.slot-set table { - width: 77px; -} - -.slot-set.pos-slot-p table { - width: 100%; -} - -.index-card .defense-slot-set { - width: 65px; -} - -.index-card .defense-slot-set .player-name { - font-stretch: 70%; -} - -.container .row { - width: 100%; - display: flex; - align-items: center; -} - header { background-color: #cadcf9; - font-family: "Oswald"; - /* font-size: 8.8px; */ - /* outline: 1px solid black; */ - /* height: var(--row-height); */ + height: var(--header-height); width: auto; text-align: center; padding-left: 10px; padding-right: 10px; - border: 0.5px solid black; - z-index: 1; + border-bottom: var(--section-border); } .cell-checkbox { @@ -575,18 +567,12 @@ header { font-weight: bold; } -.gametitle { - font-weight: bold; - text-transform: uppercase; +.event-title { font-stretch: semi-condensed; } .homeaway { - text-transform: uppercase; - font-stretch: normal; - font-weight: bolder; - float: right; - text-transform: uppercase; + font-weight: 900; } .cell-smalltext { @@ -626,42 +612,32 @@ header { font-stretch: condensed; } -.available-status-code-1 { +#roster-and-history { + --border: var(--section-border); +} +#roster-and-history table tr td.available-status-code-1, #roster-and-history table tr .available-status-code-1.position { color: rgb(0, 85, 0); background-color: #b7e1cd; } - -.available-status-code-0 { +#roster-and-history table tr td.available-status-code-0, #roster-and-history table tr .available-status-code-0.position { color: rgb(170, 0, 0); background-color: #f4c7c3; } - -.past.available-status-code-0, -.past.available-status-code-null { +#roster-and-history table tr td.past.available-status-code-0, #roster-and-history table tr .past.available-status-code-0.position, #roster-and-history table tr td.past.available-status-code-null, #roster-and-history table tr .past.available-status-code-null.position { color: var(--color-grey-600); background-color: inherit; } - -.past.available-status-code-1.Y { +#roster-and-history table tr td.past.available-status-code-1.Y, #roster-and-history table tr .past.available-status-code-1.Y.position { color: inherit; background-color: var(--color-warning); } - -.available-status-code-2 { +#roster-and-history table tr td.available-status-code-2, #roster-and-history table tr .available-status-code-2.position { color: blue; background-color: #acc9fe; } - -#roster-and-history .player-name { - font-stretch: 95%; -} - -.starting { - font-weight: bold; -} - -#roster-and-history thead { +#roster-and-history table thead tr { border: black solid 1px; + height: var(--header-height); } #roster-and-history > div > table { /* font-size: 10.5px; */ @@ -669,19 +645,34 @@ header { line-height: 1em; /* outline: 0.5px black; */ } -#roster-and-history td, #roster-and-history th { +#roster-and-history tr.starting-today td.jersey-number, #roster-and-history tr.starting-today .jersey-number.position, #roster-and-history tr.starting-today td.player-name, #roster-and-history tr.starting-today .player-name.position { + font-weight: bold; +} +#roster-and-history .player-name { + font-stretch: 95%; +} +#roster-and-history .jersey-number { + font-family: var(--monospace-font); + width: 2ch; + text-align: right; + overflow: hidden; +} +#roster-and-history tr + tr { + border-top: var(--border); +} +#roster-and-history td, #roster-and-history .position, #roster-and-history th { border-left: none; border-right: none; padding: 0.2em 0.1em 0.2em 0.1em; /* top right bottom left */ } -#roster-and-history td.availability-on-day, #roster-and-history th.availability-on-day { +#roster-and-history td.availability-on-day, #roster-and-history .position, #roster-and-history th.availability-on-day { font-family: var(--monospace-font); font-stretch: 60%; text-align: center; max-width: 0.8em; min-width: 0.8em; } -#roster-and-history td.availability-on-day.future, #roster-and-history td.availability-on-day.past, #roster-and-history th.availability-on-day.future, #roster-and-history th.availability-on-day.past { +#roster-and-history td.availability-on-day.future, #roster-and-history .future.position, #roster-and-history td.availability-on-day.past, #roster-and-history .past.position, #roster-and-history th.availability-on-day.future, #roster-and-history th.availability-on-day.past { font-family: var(--monospace-font); font-stretch: condensed; font-weight: normal; @@ -689,46 +680,54 @@ header { padding: 0.1em; text-transform: uppercase; } -#roster-and-history td.position-capability, #roster-and-history th.position-capability { +#roster-and-history td.position-capability, #roster-and-history .position-capability.position, #roster-and-history th.position-capability { font-size: 8px; font-stretch: 50%; width: 5px; text-align: center; padding: 0; } -#roster-and-history td.player-stats, #roster-and-history th.player-stats { +#roster-and-history td.spacer, #roster-and-history .spacer.position, #roster-and-history th.spacer { + display: none; +} +#roster-and-history td.spacer.first-of-group, #roster-and-history .spacer.first-of-group.position, #roster-and-history td.spacer.last-of-group, #roster-and-history .spacer.last-of-group.position, #roster-and-history th.spacer.first-of-group, #roster-and-history th.spacer.last-of-group { + border: none; +} +#roster-and-history td.player-stats, #roster-and-history .player-stats.position, #roster-and-history th.player-stats { display: none; font-family: var(--monospace-font); font-size: 1em; font-stretch: 60%; font-weight: 300; } -#roster-and-history td.player-stats .delimiter, -#roster-and-history td.player-stats .decimal-point, #roster-and-history th.player-stats .delimiter, +#roster-and-history td.player-stats .delimiter, #roster-and-history .player-stats.position .delimiter, +#roster-and-history td.player-stats .decimal-point, +#roster-and-history .player-stats.position .decimal-point, #roster-and-history th.player-stats .delimiter, #roster-and-history th.player-stats .decimal-point { font-family: Helvetica Now; font-stretch: expanded; color: var(--color-grey-500); } -#roster-and-history td.player-stats .decimal-point, #roster-and-history th.player-stats .decimal-point { +#roster-and-history td.player-stats .decimal-point, #roster-and-history .player-stats.position .decimal-point, #roster-and-history th.player-stats .decimal-point { color: rgba(0, 0, 0, 0); } -#roster-and-history td.player-stats .delimiter, #roster-and-history th.player-stats .delimiter { +#roster-and-history td.player-stats .delimiter, #roster-and-history .player-stats.position .delimiter, #roster-and-history th.player-stats .delimiter { color: var(--color-grey-500); } -#roster-and-history td.player-name { - color: black; +#roster-and-history td.player-name, #roster-and-history .player-name.position { + color: black !important; text-align: left; font-stretch: 95%; } -#roster-and-history td.jersey-number { - color: black; - border-left: 0.5px solid lightgrey; +#roster-and-history td.jersey-number, #roster-and-history .jersey-number.position { + color: black !important; } -#roster-and-history colgroup { +#roster-and-history .first-of-group { border-left-width: 1px; border-left-style: solid; border-left-color: black; +} +#roster-and-history .last-of-group { border-right-width: 1px; border-right-style: solid; border-right-color: black; @@ -736,14 +735,12 @@ header { #roster-and-history col.player-stats { border: inherit; } -#roster-and-history th { +#roster-and-history table tr:nth-child(odd) th { background-color: #cadcf9; color: black; - border: none; } -#roster-and-history th.availability-on-day div { +#roster-and-history table tr:nth-child(odd) th.availability-on-day div, #roster-and-history table tr:nth-child(odd) th.position div { transform: rotate(270deg); - margin-bottom: -5; /* font-stretch: 40%; */ font-stretch: 75%; font-weight: 500; @@ -755,16 +752,65 @@ header { #roster-and-history tbody { border-bottom: solid black 1px; } -#roster-and-history tr.border-top { +#roster-and-history tr.border-top td, #roster-and-history tr.border-top .position, #roster-and-history tr.border-top th { border-top: 1px solid black; } -td.position-capability:not(:empty) { +.letter .eventsheet.quarters header { + font-size: xx-large; +} +.letter .eventsheet.quarters .lineup-card table, .letter .eventsheet.quarters .lineup-card #roster-and-history table, #roster-and-history .letter .eventsheet.quarters .lineup-card table, .letter .eventsheet.quarters #roster-and-history .lineup-card table { + font-size: 23; +} +.letter .eventsheet.quarters #defense-pane .slot-set.pos-p { + align-items: start; +} +.letter .eventsheet.quarters #roster-and-history .spacer { + display: table-cell; + width: 30%; +} +.letter .eventsheet.quarters #roster-and-history td.position.last-of-group, .letter .eventsheet.quarters #roster-and-history .position.last-of-group { + border-right: none; +} +.letter .eventsheet.quarters #roster-and-history .container { + --padding: 2px; + display: block; + flex: none; + transform: rotate(90deg) translateY(-100%); + transform-origin: top left; + height: calc(4.25in - 2 * var(--page-margin) - 2 * var(--padding)); + width: calc(5.5in - 2 * var(--page-margin) - 2 * var(--padding)); + padding: var(--padding); +} +.letter .eventsheet.quarters #roster-and-history table { + font-size: 11; + height: 100%; +} +.letter .eventsheet.quarters #roster-and-history table thead tr { + height: inherit; +} +.letter .eventsheet.quarters #roster-and-history table thead tr th { + padding-top: 2px; + padding-bottom: 2px; +} +.letter .eventsheet.quarters #roster-and-history table th.availability-on-day div, .letter .eventsheet.quarters #roster-and-history table th.position div { + transform: none; + text-align: center; +} +.letter .eventsheet.quarters #roster-and-history #defense-pane .slot-set.pos-p { + align-items: start; +} + +table tr td.position-capability:not(:empty), #roster-and-history table tr td.position-capability:not(:empty), table tr #roster-and-history .position-capability.position:not(:empty), #roster-and-history table tr .position-capability.position:not(:empty) { color: var(--color-grey-700); background-color: var(--color-grey-200); } -td.is-present-checkbox { +table tr td.position-capability:empty, #roster-and-history table tr td.position-capability:empty, table tr #roster-and-history .position-capability.position:empty, #roster-and-history table tr .position-capability.position:empty { + background-color: white; +} + +table tr td.is-present-checkbox, #roster-and-history table tr td.is-present-checkbox, table tr #roster-and-history .is-present-checkbox.position, #roster-and-history table tr .is-present-checkbox.position { font-size: 0.5em; text-align: center; color: white; @@ -772,11 +818,11 @@ td.is-present-checkbox { 1px 1px 0 #000; */ } -td.is-present-checkbox.available-status-code-0 > span { +td.is-present-checkbox.available-status-code-0 > span, #roster-and-history .is-present-checkbox.available-status-code-0.position > span { display: none; } -td.is-present-checkbox.available-status-code-None > span { +td.is-present-checkbox.available-status-code-None > span, #roster-and-history .is-present-checkbox.available-status-code-None.position > span { display: none; } @@ -786,7 +832,6 @@ td.is-present-checkbox.available-status-code-None > span { #front-cover Header { font-family: "Helvetica Now"; font-weight: 600; - line-height: 1.5em; background-color: #323669; color: white; display: inline-flex; @@ -794,26 +839,41 @@ td.is-present-checkbox.available-status-code-None > span { padding-left: 5px; padding-right: 5px; } -#front-cover .game-number, #front-cover .homeaway { +#front-cover Header .title { display: grid; + font-family: "Futura Now"; + flex-grow: 1; align-content: center; - width: 1.4em; + font-size: 14px; } -#front-cover .homeaway { +#front-cover Header .homeaway { font-weight: 800; font-size: xx-large; } -#front-cover .game-number { +#front-cover Header .game-number, #front-cover Header .homeaway { + display: grid; + align-content: center; +} +#front-cover Header .game-number { font-size: large; font-stretch: extra-condensed; font-weight: 700; text-wrap: nowrap; } -#front-cover .title { - display: grid; - font-size: small; - flex-grow: 1; - align-content: center; +#front-cover > div { + width: inherit; +} +#front-cover th { + background-color: whitesmoke; +} +#front-cover th, #front-cover td, #front-cover #roster-and-history .position, #roster-and-history #front-cover .position { + font-family: "Futura Now"; + border: solid 0.5px grey; +} +#front-cover .conjuction { + text-align: center; + font-family: "Futura Now"; + text-transform: none; } #front-cover .head-to-head { padding: 5px; @@ -823,9 +883,10 @@ td.is-present-checkbox.available-status-code-None > span { #front-cover .opponent, #front-cover .team { text-align: center; font-weight: 800; - font-size: x-large; + font-size: xx-large; align-items: center; font-family: "Pacifico"; + text-transform: none; display: inline-flex; width: 100%; flex-grow: 1; diff --git a/src/public/css/eventsheet.css.map b/src/public/css/eventsheet.css.map index 0c9e08b..a0d3250 100644 --- a/src/public/css/eventsheet.css.map +++ b/src/public/css/eventsheet.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../../scss/eventsheet.scss"],"names":[],"mappings":";AAAQ;AACA;AACA;AACA;AACA;AAER;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAGF;AACA;EACE;IACE;;EAEF;IACE;IACA;;;AAIJ;AACA;EACE;IACE;;EAEF;IACE;;EAEF;IACE;IACA;;;AAIJ;EACE;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAKA;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAQR;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;AACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;;AAEJ;EACI;EACA;;AAEJ;EACI;EACA;;AAEJ;EACI;;;AAKN;EACE;;;AAGF;AAAA;EAEE;EACA;EACA;EACA,qBACE;;;AAIJ;AAAA;EAEE;EACA;EACA;EACA,qBACE;;;AAIJ;AAAA;AAAA;AAAA;EAIE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;AAEA;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAQN;EACE;;;AAGF;AACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;;AAGF;EACE;;;AAGF;EACE;;AACA;EACE;;AAEF;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;AAAA;EAEE;;;AAGF;AAAA;EAEE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAKA;EACE;EACA;EACA;EACA,qBACE;;AAIJ;EACE;;AAGF;EACE;;AAGF;AACE;EACA;EACA;EACA;AACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;EACA;;AAGF;EACE;EACA;;AACA;EACE;;AAQJ;EACE;EACA;EACA;;AAEF;EACE;;;AAON;EACE;;AAGF;EACE;;AAIA;EACE;EACA;;AAMF;EACE;;AAGF;EAOE;EACA;EACA;EACA;;AATA;EACE;;AACA;EACE;;;AAeV;EACE;EACA;EACA;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAMI;EACE,SALM;;AAIR;EACE,SALM;;AAIR;EACE,SALM;;AAIR;EACE,SALM;;AAIR;EACE,SALM;;AAIR;EACE,SALM;;AAIR;EACE,SALM;;AAIR;EACE,SALM;;AAIR;EACE,SALM;;AAUZ;EACE;EAEA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EAIE;EACA;EACA;;AALA;EACE;;AAKF;EACI;;;AASV;EACE;AACA;EACA;EAEA;EACA;AACA;;AAEA;EACE;EACA;;AAGF;EACE;;AACA;EACE;;;AAON;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;AACA;AACA;AACA;EACA;EAEA;EACA;EACA;EACA;EACA;;;AAKF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAEF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;AAAA;EAEE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AASA;EACE;;AAEF;AACE;EACA;EACA;AACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAGF;EAEE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACI;EACA;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;EACA;;AAEA;AAAA;AAAA;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAMN;EACE;EACA;EACA;;AAEF;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EAEE;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;AACA;EACA;EACA;EACA;;AAQJ;EACE;;AAGF;EACE;;AAGF;EACE;;;AAOJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;AACA;AAAA;;;AAIF;EACE;;;AAGF;EACE;;;AAGF;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACI;EACA;EACA;EACA;;AAGJ;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE","file":"eventsheet.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../../scss/eventsheet.scss"],"names":[],"mappings":";AAAQ;AACA;AACA;AACA;AACA;AACA;AAER;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIF;AACA;EACE;IACE;;EAEF;IACE;;EAEF;IACE;IACA;;;AAIJ;AACA;EACE;IACE;;EAEF;IACE;;EAEF;IACE;IACA;IACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;AACA;EAA+B;EAAc;;;AAC7C;EAA+B;EAAc;;;AAC7C;EAA+B;EAAc;;;AAE7C;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAEF;EACE;EACA;;AAEA;EACE;;AAMkB;EAChB;;AAGiB;EACjB;;;AAOR;EACE;;;AAGF;EACE;;;AAGF;EACE;;AACA;EACE;;AACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAGF;EACE;;AAGF;EACE;;;AAMN;EACI;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;;AAIN;EACE;;;AAGF;EACE;EACE;EACA;EACA;EACA;;AACA;EACE;;;AAIN;EACE;EACE;EACA;EACA;EACA;;AACA;EACE;;;AAIN;EACE;EAEA;EAEA;;AAEA;EACE;EACA;EACA;EACA;;AACA;EACE;;AAIJ;EACE;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAMN;EACE;EACA;EACA;;AAGF;EAEE;;AAGF;AACE;;AACA;EACE;;AACA;EACE;;AAGJ;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAKF;EAEA;;AAIA;EACE;EACA;;AAEF;EACE;;AAKF;EACE;;AACA;EACE;;AAGJ;EACE;;AAGF;EACE;;;AAMJ;EACE;;AAEF;EACE;;AACA;EACE;;;AAOJ;EACE;EACA;EACA;EACA,qBACE;;AAIJ;EACE;;AAGF;EACE;;AAGF;AACE;EACA;EACA;EACA;AACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGE;EACA;EACA;EACA;;AAGA;EACE;EACA;EACA;;AAIJ;EACE;EACA;;AAGF;EACE;EACA;;AACA;EACE;;AAQJ;EACE;EACA;EACA;;AAEF;EACE;;;AAON;EACE;;AAGF;EACE;;AAIA;EACE;EACA;;AAMF;EACE;;AAGF;EAOE;EACA;EACA;EACA;;AATA;EACE;;AACA;EACE;;;AAcV;EACE;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;;AAIJ;EACE;EACA;;AAIA;EACE;;AAGF;EACE;EACA;EACA;;AAEE;EACE;;AAEM;EACN;;AAEF;EACA;EACA;EACA;;AAQA;EACE;;AACA;EACA,SA/BM;;AA4BR;EACE;;AACA;EACA,SA/BM;;AA4BR;EACE;;AACA;EACA,SA/BM;;AA4BR;EACE;;AACA;EACA,SA/BM;;AA4BR;EACE;;AACA;EACA,SA/BM;;AA4BR;EACE;;AACA;EACA,SA/BM;;AA4BR;EACE;;AACA;EACA,SA/BM;;AA4BR;EACE;;AACA;EACA,SA/BM;;AA4BR;EACE;;AACA;EACA,SA/BM;;AAoCZ;EACE;EAEA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EAIE;EACA;EACA;;AALA;EACE;;AAKF;EACE;;AACA;EACE;;;AASV;EACE;AACA;EACA;EAEA;EACA;AACA;;AAEA;EACE;EACA;;AAGF;EACE;;AACA;EACE;;;AAMN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAEF;EACE;;;AAGF;EACE;;;AAKF;EACE;;AAME;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EAEE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;EACA;;AAEF;AACE;EACA;EACA;AACA;;AAIA;EACA;;AAKF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAOF;EACE;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAGF;EAEE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACI;EACA;EACA;EACA;EACA;;AAEJ;EACE;;AACA;EACE;;AAGJ;EACI;EACA;EACA;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAMN;EACE;EACA;EACA;;AAEF;EACE;;AAIJ;EACE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EAEE;;AAGF;EACE;EACA;;AAEA;EACE;AACA;EACA;EACA;EACA;;AAQJ;EACE;;AAGF;EACE;;AAGa;EACb;;;AAMF;EACE;;AAEF;EACE;;AAEF;EACE;;AAIA;EACE;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EAQE;EACA;;AARA;EACE;;AACA;EACE;EACA;;AAWJ;EACE;EACA;;AAQJ;EACE;;;AAKN;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;AACA;AAAA;;;AAIF;EACE;;;AAGF;EACE;;;AAGF;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAIJ;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE","file":"eventsheet.css"} \ No newline at end of file diff --git a/src/public/js/eventlineup.js b/src/public/js/eventlineup.js index dd59524..df5034b 100644 --- a/src/public/js/eventlineup.js +++ b/src/public/js/eventlineup.js @@ -323,6 +323,7 @@ async function onSubmit(form, event) { event.submitter.blur() waiting_icon.classList.add("u-hidden"); success_icon.classList.remove("u-hidden"); + console.log(text); // success_icon.querySelector("span.message").innerHTML = text; }) .catch((error) => { @@ -331,7 +332,8 @@ async function onSubmit(form, event) { failure_icon.classList.remove("u-hidden"); console.log(error); // success_icon.querySelector("span.message").innerHTML = error; - }); + }) + .finally(()=>{location.reload()});//refresh page setTimeout(() => { [waiting_icon, success_icon, failure_icon].forEach(e=>e.classList.add('u-hidden')) teamsnap_icon.classList.remove('u-hidden') @@ -637,10 +639,11 @@ function insertLineup(direction, teamId, eventId, element) { function initSlots () { const slots = Array.from(document.querySelectorAll('.lineup-slot')) slots.forEach(slot=>{ - console.log(slot,`.${slot.dataset.initialSlotset}`) - const parent = document.querySelector(`#${slot.dataset.initialSlotset}`) - parent.appendChild(slot) - slot.removeAttribute('data-initial-slotset') + if (slot.dataset.initialSlotset) { + const parent = document.querySelector(`#${slot.dataset.initialSlotset} .slot-set`) + parent.appendChild(slot) + slot.removeAttribute('data-initial-slotset') + } }) } diff --git a/src/routes/eventsheet.js b/src/routes/eventsheet.js index dc9e7c1..20fac46 100644 --- a/src/routes/eventsheet.js +++ b/src/routes/eventsheet.js @@ -30,6 +30,8 @@ router.get("/:team_id([0-9]+)/event/:event_id([0-9]+)/sheet", async (req,res) => } ) +router.get("/lineup/sheet/blank", eventsSheetController.getEventSheetBlank ) + router.post("/:team_id([0-9]+)/event/:event_id([0-9]+)/lineup/:event_lineup_id([0-9]+)/sheet", upload.none(), eventsSheetController.getEventSheet ) module.exports = {router} \ No newline at end of file diff --git a/src/scss/eventsheet.scss b/src/scss/eventsheet.scss index a8d1b0f..2ef7155 100644 --- a/src/scss/eventsheet.scss +++ b/src/scss/eventsheet.scss @@ -3,60 +3,7 @@ @import url('https://fonts.googleapis.com/css2?family=Graduate'); @import url('https://fonts.googleapis.com/css2?family=Inconsolata:wdth,wght@50..200,200..900&display=swap'); @import url('/font/helvetica-now/stylesheet.css'); - -@font-face { - font-family: "Futura Now"; - src: url("/font/futura-now/futura-now.ttf") format("truetype"); - font-weight: 125 900; - font-stretch: 50% 150%; -} - -@page { - margin: 0; -} - -/** For Print **/ -@media print { - body { - margin:0; - } - body .sheet { - size: B5; - padding: 0.175in; - } -} - -/** For screen preview **/ -@media screen { - body .sheet { - padding: 0.175in; - } - body { - background: #e0e0e0; - } - .sheet { - background: white; - box-shadow: 0 0.5mm 2mm rgba(0, 0, 0, 0.3); - } -} - -.sheet { - overflow: hidden; - position: relative; - box-sizing: border-box; - page-break-after: always; -} - -/** Paper sizes **/ -body.B5 .sheet { - width: 176mm; - height: 250mm; -} - -body.index-card .sheet { - width: 3.5in; - height: 5in; -} +@import url('/font/futura-now/stylesheet.css'); :root { --color-success: #b7e1cd; @@ -72,18 +19,63 @@ body.index-card .sheet { --color-grey-700: #495057; --color-grey-800: #343a40; --color-grey-900: #212529; + --header-height: 17px; --row-height: 14px; --monospace-font: "Inconsolata", monospace; + --section-border: 0.5px solid black; } + +/** For Print **/ +@media print { + :root { + margin: 0; + } + body { + margin:0; + } + body .sheet { + padding: 0.175in; + background:white; + } +} + +/** For screen preview **/ +@media screen { + body .sheet { + padding: 0.175in; + } + body { + background: #e0e0e0; + } + .sheet { + margin: auto; + margin-bottom: 12px; + box-shadow: 0 0.5mm 2mm rgba(0, 0, 0, 0.3); + } +} + +.sheet { + overflow: hidden; + position: relative; + box-sizing: border-box; + page-break-after: always; + background: white; +} + +/** Paper sizes **/ +body.B5 .sheet { width: 176mm; height: 250mm;} +body.index-card .sheet { width: 3.5in; height: 5in;} +body.letter .sheet { width: 8.5in; height: 11in; } + body { font-family: "Helvetica Now", "Helvetica", sans-serif; position: relative; font-size: 11px; + text-transform: uppercase; } table { - position: inherit; font-size: inherit; border-collapse: collapse; empty-cells: show; @@ -92,59 +84,32 @@ table { overflow-x: hidden; overflow-y: hidden; width: 100%; - border: 0.5px solid black; - display: inline-table; + th { + color: var(--color-grey-700); + } + th, td { + overflow: hidden; + padding: 0 2px 0 2px; - tr { - border-bottom-width: 0.5px; - border-color: grey; - border-bottom-style: solid; - - &:nth-child(odd) { - background-color: rgb(242, 242, 242, 0.85); + &:empty::after { + content: "\00a0"; } - - &:nth-child(even) { - background-color: rgb(256, 256, 256, 0.85); - } - - th { - font-stretch: extra-condensed; - width: 1em; - text-align: center; - text-transform: uppercase; - } - - - td { - &.player-name { - text-transform: uppercase; - font-stretch: 75%; - } - &.position, &.jersey-number { - font-family: var(--monospace-font); - width: 2ch; - text-align: right; - overflow: hidden; - } - - } - - th, td { - border-left: 0.5px solid grey; - border-right: 0.5px solid grey; - overflow: hidden; - padding: 0 2px 0 2px; - - &:empty::after { - content: "\00a0"; - } - } - } + &.striped { + tr { + &:nth-child(odd) {td, th { + background-color: whitesmoke; + }} + + &:nth-child(even) {td,th { + background-color: white; + }} + } + } } + .float-right { float: right; } @@ -153,217 +118,198 @@ table { float: left; } -.B5 > .eventsheet { - display: grid; - grid-template-columns: 1fr 1fr; - grid-template-rows: 1fr 1fr; - column-gap: 0.35in; - row-gap: 0.35in; - background-size: 100%; -} - -.eventsheet > section { - box-sizing: content-box; - overflow: hidden; - /* outline: 0.5px dashed lightgrey; */ - display: flex; - flex-direction: column; - align-items: stretch; - - > div { +.eventsheet{ + --page-margin: 0.175in; + &:has(section) { + display: grid; + section { + --divider-border: lightgrey dashed 1px; + box-sizing: content-box; + overflow: hidden; display: flex; - flex: 1; + flex-direction: column; align-items: stretch; - height: auto; - } - - &.NW { - grid-area: 1 / 1 / 2 / 2; - } - &.NE { - grid-area: 1 / 2 / 2 / 3; - } - &.SW { - grid-area: 2 / 1 / 3 / 2; - } - &.SE { - grid-area: 2 / 2 / 3 / 3; + outline-style: solid; + outline-width: calc(var(--divider-border)/4); + outline-color: lightgray; + + > div { + display: flex; + flex: 1; + align-items: stretch; + height: auto; + width:100% } -} - -.eventsheet > .section-divider { - position: absolute; - display: grid; - grid-template-columns: repeat(2, 1fr); - grid-template-rows: repeat(2, 1fr); - grid-column-gap: 0px; - grid-row-gap: 0px; - height: 100%; - width: 100%; - box-sizing: border-box; - --divider-border: lightgrey dashed 1px; - - .NW { + &.NW { grid-area: 1 / 1 / 2 / 2; - border-right:var(--divider-border); - border-bottom:var(--divider-border); } - .NE { + &.NE { grid-area: 1 / 2 / 2 / 3; - border-bottom:var(--divider-border); - } - .SW { + } + &.SW { grid-area: 2 / 1 / 3 / 2; - border-right:var(--divider-border); - } - .SE { + } + &.SE { grid-area: 2 / 2 / 3 / 3; + } + + &.NW .divider, &.SW .divider { + border-right:var(--divider-border); } + &.NW .divider, &.NE .divider { + border-bottom:var(--divider-border); + } + } + } } -.lineup-card th { - width: inherit; +.eventsheet.quarters { + --section-margin: calc(var(--page-margin)/2); + grid-template-columns: 1fr 1fr; + grid-template-rows: 1fr 1fr; + column-gap: calc(var(--page-margin)*2); + row-gap: calc(var(--page-margin)*2); + outline-offset: var(--section-margin); + section { + outline-offset: var(--page-margin); + } } -#lineup-card-dugout div.grid-container, -#lineup-card-dugout-blank div.grid-container { - display: grid; - grid-template-columns: 60% auto; - grid-template-rows: fit-content(16px) auto; - grid-template-areas: - "header header" - "sarting-lineup-table substitution-table"; +.letter .eventsheet.quarters { + --header-height: 0.5in; } -#lineup-card-exchange div.grid-container, -#lineup-card-exchange-blank div.grid-container { - display: grid; - grid-template-columns: auto; - grid-template-rows: fit-content(16px) auto; - grid-template-areas: - "header" - "sarting-lineup-table"; +.letter .eventsheet.index-cards-4x6 { + --section-margin: calc(var(--page-margin)/2); + grid-template-columns: 1fr 1fr; + grid-template-rows: 1fr 125mm; + column-gap: calc(var(--page-margin)*2); + row-gap: calc(var(--page-margin)*2); + section { + outline-offset: var(--page-margin); + } } -#lineup-card-exchange .substitution, -#lineup-card-exchange .homeaway, -#lineup-card-exchange-blank .substitution, -#lineup-card-exchange-blank .homeaway { - display: none; +.letter .eventsheet.index-cards-3x5 { + --section-margin: calc(var(--page-margin)/2); + grid-template-columns: 3in 3in; + grid-template-rows: 5in 5in; + column-gap: calc(var(--page-margin)*2); + row-gap: calc(var(--page-margin)*2); + section { + outline-offset: var(--page-margin); + } } -.lineup-card div.grid-container > header { - grid-area: "header"; - font-size: 14px; - font-weight: bold; -} - -.lineup-card div.grid-container > header:empty::after { - content: "\00a0"; -} - -div.grid-container > .starting-lineup-table { - grid-area: "starting-lineup-table"; -} - -div.grid-container > .substitution-table { - grid-area: "substitution-table"; -} - -section.lineup-card { +.lineup-card { counter-reset: lineup-sequence-counter 0; + + --border: 0.5px solid grey; + + border: var(--section-border); + + header { + text-transform: uppercase; + border-style: none; + border-bottom: var(--border); + height: var(--header-height); + &:empty::after { + content: "\00a0"; + } + } + + th { + width: inherit; + &.sequence { + counter-increment: lineup-sequence-counter 1; + color: var(--color-grey-600); + font-size: inherit; + width: 2ch; + font-stretch: 50%; + border-right: var(--border); + &.counter::before { + content: counter(lineup-sequence-counter); + } + + } + } thead th { color: var(--color-grey-600); font-size: 0.7em; + border-bottom: var(--border); + } + + table { + @extend table, .striped; + font-size: 21px; } - th.sequence { - counter-increment: lineup-sequence-counter 1; - color: var(--color-grey-600); - font-size: inherit; - width: 2ch; - &.counter::before { - content: counter(lineup-sequence-counter); + td { + /* height: 34px; */ + &.substitution { + width: 8ch; + &::after { + content: ""; + } + } + &.position, &.jersey-number { + width: 2ch; + } + &.position, &.jersey-number, &.substitution { + font-family: var(--monospace-font); + border-left: var(--border); + text-align: right; + padding-left: 2.5px; + padding-right: 2.5px; } - } + + tr + tr { + td, th{ + // border-top: 1px solid black; + border-top: var(--border); + } } + &.dugout { + td.player-name { + width: 10ch; + font-stretch: 75%; + } + .position, .jersey-number, .substitution { + font-stretch: 75%; + } + } + + &.exchange { + header { + text-align: center; + .float-left, .float-right { + float:none; + } + } + .player-name { + font-stretch: 100%; + } + + .homeaway, .substitution { + display: none; + } + } } - -.lineup-card table { - font-size: 21px; -} - -.lineup-card td { - /* height: 34px; */ -} - -.lineup-card td.substitution { - width: 8ch; -} - -.lineup-card td.substitution::after { - content: ""; -} - -#lineup-card-exchange tr, -#lineup-card-exchange-blank tr, -#lineup-card-dugout .starting-lineup-table tr, -#lineup-card-dugout-blank .starting-lineup-table tr, -#lineup-card-dugout .substitution-table tr:nth-child(odd) { - border-top: 1px solid black; -} - -#lineup-card-exchange tr, -#lineup-card-exchange-blank tr, -#lineup-card-dugout .starting-lineup-table tr, -#lineup-card-dugout-blank .starting-lineup-table tr, -#lineup-card-dugout .substitution-table tr:nth-child(even) { - border-bottom: 1px solid black; -} - -td.substitution { - border-left: 1px solid black; -} - section.blank { - filter: opacity(0.4); - img, header { - filter: grayscale(1); + svg, header { + filter: grayscale(1) opacity(0.4); } - td.substitution { - border-width: 0.5; - } -} - -#lineup-card-exchange td.player-name { - font-stretch: 100%; -} - -#lineup-card-dugout td.player-name { - width: 10ch; -} - -.lineup-card .position, -.lineup-card .jersey-number { - width: 2ch; -} - -#lineup-card-dugout .position, -#lineup-card-dugout .jersey-number { - font-stretch: 75%; - padding-left: 2.5px; - padding-right: 2.5px; -} - -.lineup-card header { - font-size: inherit; - text-transform: uppercase; - font-stretch: 85%; + > div { + filter: opacity(0.4); + td.substitution { + border-width: 0.5; + } + } } @@ -401,11 +347,13 @@ section.blank { border-style: none; tr { + td, th { background-color: white; outline: none; border-bottom: 0.5px solid var(--color-grey-500); + } - :last-child { + :last-child td { background-color: white; outline: none; border-bottom-style: none; @@ -454,7 +402,7 @@ section.blank { table { font-size: 14px; width: 120px; - tbody > tr:last-child { + tbody > tr:last-child td { // display: none; } } @@ -481,14 +429,15 @@ section.blank { } +#defense-card { + border: var(--section-border); +} #defense-pane { position: relative; grid-area: defense; padding: 4px 4px 0px 4px; /* top right bottom left */ display: flex; - border: 0.5px solid grey; - // border-bottom: 0.5px solid grey; .field-container { display: grid; @@ -499,9 +448,23 @@ section.blank { z-index: 2; } - img { + svg { position: absolute; + stroke-linecap: round; + stroke-miterlimit: 1.5; z-index: -1; + opacity: 70%; + #outfield-path { + stroke: #4AA1D5; + fill: none; + stroke-width: 4px; + } + #infield-path { + stroke: #4AA1D5; + fill: #D1E6F7; + stroke-width: 4px; + fill-opacity: 50%; + } } .slot-set { @@ -510,11 +473,37 @@ section.blank { $positions: "cf", "lf", "rf", "ss", "2b", "3b", "1b", "c", "p"; + .player-name { + font-stretch: 80%; + } + + table { + --border: grey solid 0.5px; + border: var(--border); + opacity: 85%; + tr { + &:first-child th { + border-bottom: var(--border); + } + & + tr {td,th { + border-top: var(--border); + }} + th.position { + font-family: var(--monospace-font); + width: 2ch; + text-align: right; + + } + } + } + @each $position in $positions { &.pos-#{$position} tr:first-child { - th.position:empty::after { + th.position:empty{ + border-right: var(--border); + &::after { content: $position; - } + }} } } @@ -566,9 +555,11 @@ section.blank { align-items: end; margin-bottom: 4px; grid-area: 6 / 1 / 7 / 5; - tr.substitute .position:empty::after{ + tr.substitute .position:empty{ + border-right: var(--border); + &::after{ content: "RP"; - } + }} } @@ -599,46 +590,16 @@ section.blank { } - -.slot-set table { - width: 77px; -} - -.slot-set.pos-slot-p table { - width: 100%; -} - -.index-card .defense-slot-set { - width: 65px; -} - -.index-card .defense-slot-set .player-name { - font-stretch: 70%; -} - -.container .row { - width: 100%; - display: flex; - align-items: center; -} - header { background-color: #cadcf9; - font-family: "Oswald"; - /* font-size: 8.8px; */ - /* outline: 1px solid black; */ - /* height: var(--row-height); */ + height: var(--header-height); width: auto; - // grid-area: header; text-align: center; padding-left: 10px; padding-right: 10px; - border: 0.5px solid black; - z-index: 1; + border-bottom: var(--section-border); } - - .cell-checkbox { font-size: 0.75em; } @@ -647,18 +608,12 @@ header { font-weight: bold; } -.gametitle { - font-weight: bold; - text-transform: uppercase; +.event-title { font-stretch: semi-condensed; } .homeaway { - text-transform: uppercase; - font-stretch: normal; - font-weight: bolder; - float: right; - text-transform: uppercase; + font-weight: 900; } .cell-smalltext { @@ -697,48 +652,45 @@ header { font-stretch: condensed; } -.available-status-code-1 { - color: rgb(0, 85, 0); - background-color: #b7e1cd; -} -.available-status-code-0 { - color: rgb(170, 0, 0); - background-color: #f4c7c3; -} - -.past.available-status-code-0, -.past.available-status-code-null { - color: var(--color-grey-600); - background-color: inherit; -} - -.past.available-status-code-1.Y { - color: inherit; - background-color: var(--color-warning); -} - -.available-status-code-2 { - color: blue; - background-color: #acc9fe; -} - -#roster-and-history .player-name { - font-stretch: 95%; -} - -.starting { - font-weight: bold; -} #roster-and-history { - // #today-availability { - // font-stretch: normal; - // text-transform: uppercase; - // font-size: 0.8em; - // } - thead { + --border: var(--section-border); + table { + @extend table, .striped; + } + + table tr td { + &.available-status-code-1 { + color: rgb(0, 85, 0); + background-color: #b7e1cd; + } + + &.available-status-code-0 { + color: rgb(170, 0, 0); + background-color: #f4c7c3; + } + + &.past.available-status-code-0, + &.past.available-status-code-null { + color: var(--color-grey-600); + background-color: inherit; + } + + &.past.available-status-code-1.Y { + color: inherit; + background-color: var(--color-warning); + } + + &.available-status-code-2 { + color: blue; + background-color: #acc9fe; + } + } + + table thead tr { border: black solid 1px; + height: var(--header-height); } > div > table { /* font-size: 10.5px; */ @@ -747,6 +699,32 @@ header { /* outline: 0.5px black; */ } + tr.starting-today td { + &.jersey-number, &.player-name{ + font-weight: bold; + } + } + + + .player-name { + font-stretch: 95%; + } + + .jersey-number { + font-family: var(--monospace-font); + width: 2ch; + text-align: right; + overflow: hidden; + } + + .position { + @extend td, .availability-on-day + } + + tr + tr { + border-top: var(--border); + } + td, th { border-left: none; border-right: none; @@ -777,6 +755,12 @@ header { text-align: center; padding: 0; } + &.spacer { + display: none; + &.first-of-group, &.last-of-group { + border: none; + } + } &.player-stats { display:none; font-family: var(--monospace-font); @@ -803,20 +787,21 @@ header { td{ &.player-name { - color: black; + color: black !important; text-align: left; font-stretch: 95%; } &.jersey-number { - color: black; - border-left: 0.5px solid lightgrey; + color: black !important; } } - colgroup { + .first-of-group { border-left-width: 1px; border-left-style: solid; border-left-color: black; + } + .last-of-group { border-right-width: 1px; border-right-style: solid; border-right-color: black; @@ -827,14 +812,12 @@ header { border: inherit; } - th { + table tr:nth-child(odd) th { //needs to have n-thchild to override .striped background-color: #cadcf9; color: black; - border: none; &.availability-on-day div { transform: rotate(270deg); - margin-bottom: -5; /* font-stretch: 40%; */ font-stretch: 75%; font-weight: 500; @@ -854,20 +837,86 @@ header { border-bottom: solid black 1px; } - tr.border-top { + tr.border-top {td, th { border-top: 1px solid black; - } - - + }} } -td.position-capability:not(:empty) { +.letter .eventsheet.quarters { + header { + font-size: xx-large; + } + .lineup-card table { + font-size: 23; + } + #defense-pane .slot-set.pos-p { + align-items: start; + } + + #roster-and-history { + .spacer { + display:table-cell; + width: 30%; + } + + td.position.last-of-group { + border-right: none; + } + + .container { + --padding: 2px; + display: block; + flex: none; + transform: rotate(90deg) translateY(-100%); + transform-origin: top left; + height: calc(4.25in - 2 * var(--page-margin) - 2 * var(--padding)); + width: calc(5.5in - 2 * var(--page-margin) - 2 * var(--padding)); + padding: var(--padding) + } + + table { + thead tr { + height: inherit; + th { + padding-top: 2px; + padding-bottom: 2px; + } + } + font-size: 11; + height:100%; + td, th { + &.player-name { + // width: 38%; + } + } + + th.availability-on-day div { + transform: none; + text-align: center; + } + } + + .position, .availability-on-day, .is-present-checkbox { + // width: 3ch; + } + + #defense-pane .slot-set.pos-p { + align-items: start; + } +}} + + +table tr td.position-capability:not(:empty) { color: var(--color-grey-700); background-color: var(--color-grey-200); } -td.is-present-checkbox { +table tr td.position-capability:empty { + background-color: white; +} + +table tr td.is-present-checkbox { font-size: 0.5em; text-align: center; color: white; @@ -889,40 +938,57 @@ td.is-present-checkbox.available-status-code-None > span { Header { font-family: "Helvetica Now"; font-weight: 600; - line-height: 1.5em; background-color: #323669; color: white; display: inline-flex; border: none; padding-left: 5px; padding-right: 5px; - } - - .game-number, .homeaway{ - display: grid; - align-content: center; - width: 1.4em; - } - - .homeaway { - font-weight: 800; - font-size: xx-large; - } - - .game-number { - font-size: large; - font-stretch: extra-condensed; - font-weight: 700; - text-wrap: nowrap; - } - - .title { + .title { display: grid; - font-size: small; + font-family: "Futura Now"; flex-grow: 1; align-content: center; + font-size: 14px; + } + + .homeaway { + font-weight: 800; + font-size: xx-large; + } + + .game-number, .homeaway{ + display: grid; + align-content: center; + } + + .game-number { + font-size: large; + font-stretch: extra-condensed; + font-weight: 700; + text-wrap: nowrap; + } } + > div { + width: inherit; + } + + th { + background-color: whitesmoke; + } + + th, td { + font-family: "Futura Now"; + border: solid 0.5px grey; + } + + .conjuction { + text-align: center; + font-family: "Futura Now"; + text-transform: none; + } + .head-to-head { padding:5px; display: flex; @@ -932,9 +998,10 @@ td.is-present-checkbox.available-status-code-None > span { .opponent, .team { text-align: center; font-weight: 800; - font-size: x-large; + font-size: xx-large; align-items: center; font-family: 'Pacifico'; + text-transform: none; display: inline-flex; width: 100%; flex-grow:1; diff --git a/src/views/event/stats-importer.hbs b/src/views/event/stats-importer.hbs new file mode 100644 index 0000000..e69de29 diff --git a/src/views/eventlineup/partials/page_section_divider.hbs b/src/views/eventlineup/partials/page_section_divider.hbs deleted file mode 100644 index a76b945..0000000 --- a/src/views/eventlineup/partials/page_section_divider.hbs +++ /dev/null @@ -1,7 +0,0 @@ - -
-
-
-
-
-
\ No newline at end of file diff --git a/src/views/eventsheet/partials/defense_pane.hbs b/src/views/eventsheet/partials/defense_pane.hbs index daf6da0..ee31445 100644 --- a/src/views/eventsheet/partials/defense_pane.hbs +++ b/src/views/eventsheet/partials/defense_pane.hbs @@ -1,8 +1,8 @@
- + {{{embeddedSvgFromPath "/media/baseball-diamond.svg" 'baseball-diamond'}}} {{#defenseLineup event_lineup_entries members}}
- +
diff --git a/src/views/eventsheet/partials/roster_and_history.hbs b/src/views/eventsheet/partials/roster_and_history.hbs index 640b6a7..14f61ab 100644 --- a/src/views/eventsheet/partials/roster_and_history.hbs +++ b/src/views/eventsheet/partials/roster_and_history.hbs @@ -1,14 +1,16 @@
- - {{!-- --}} - + {{!-- --}} + {{!-- --}} + {{!-- --}} + {{!-- - + --}} - + - + - + {{!-- <% for timepoint, i in timeline.select{|tp| tp[:comparison_to_selected]>0}.sort{|tp| -tp[:comparison_to_selected]}.each_with_index do%> --}} {{#loopEvents upcoming_events}} - + {{/loopEvents}} {{#loopEvents recent_events}} - + {{/loopEvents}} {{!-- <% by_member.select{|m,d| !m.is_non_player}.each_with_index do |(member, d), i|%> --}} {{#rosterHistory event event_lineup_entries members availabilities}} - - + - - - + + - + - + {{#loopEvents ../upcoming_events}} {{#timepointForMember ../this ../../timeline this}} - {{/timepointForMember}} {{/loopEvents}} {{#loopEvents ../recent_events}} {{#timepointForMember ../this ../../timeline this}} - {{/timepointForMember}} diff --git a/src/views/eventsheet/sheet.hbs b/src/views/eventsheet/sheet.hbs index d19d460..0a78b7b 100644 --- a/src/views/eventsheet/sheet.hbs +++ b/src/views/eventsheet/sheet.hbs @@ -1,12 +1,11 @@ - -
- {{>page_section_divider}} -
+ +
+
- {{event.formattedTitle}} – {{dateFormat event.startDate "ddd, MMM D h:mm A" }} + {{event.formattedTitle}}
{{event.gameType}} @@ -32,18 +31,18 @@
-
-
- {{> roster_and_history - event=event - event_lineup_entries=event_lineup_entries - members=members availabilities=availabilities - recent_events=recent_events +
+
+ {{> roster_and_history + event=event + event_lineup_entries=event_lineup_entries + members=members availabilities=availabilities + recent_events=recent_events upcoming_events=upcoming_events }}
-
+
{{event.formattedTitle}}
{{event.gameType}}
@@ -83,7 +82,7 @@
-
{{event.formattedTitle}}
+
{{event.formattedTitleForMultiTeam}}
{{event.gameType}}
@@ -120,9 +119,8 @@
-
- {{>page_section_divider}} -
+
+
{{event.label}} @@ -145,10 +143,8 @@
{{# if event.opponentName}} -
-
+
vs -
@@ -180,7 +176,7 @@ {{/if}}
-
+
  @@ -210,6 +206,7 @@
+
+ Available ({{availabilitySummary.playerGoingCount}}|{{availabilitySummary.playerMaybeCount}}) .AVG / @@ -17,34 +19,38 @@ .SLG :PA PP C IOO
{{dateFormat this.startDate "ddd" }}
{{dateFormat this.startDate "ddd" }}
{{dateFormat this.startDate "ddd" }}
{{dateFormat this.startDate "ddd" }}
+
+ {{this.jerseyNumber}} + {{this.lastName}} + + {{this.benchcoach.eventLineupEntry.label}} + . 000 / @@ -56,20 +62,20 @@ : 00 {{positionCapabilityFor this "P"}}{{positionCapabilityFor this "P"}} {{positionCapabilityFor this "C"}} {{positionCapabilityFor this "IF"}}{{positionCapabilityFor this "OF"}}{{positionCapabilityFor this "OF"}} + {{this.value}} + {{this.value}}
@@ -241,7 +238,8 @@
-
+
+
@@ -275,6 +273,5 @@
-
diff --git a/src/views/eventsheet/sheet_blank.hbs b/src/views/eventsheet/sheet_blank.hbs new file mode 100644 index 0000000..a97a622 --- /dev/null +++ b/src/views/eventsheet/sheet_blank.hbs @@ -0,0 +1,248 @@ + + + +
+
+
+ {{> roster_and_history + event=event + event_lineup_entries=event_lineup_entries + members=members availabilities=availabilities + recent_events=recent_events + upcoming_events=upcoming_events + }} +
+
+
+
+
+
+
+
+
+
+
+ {{> defense_pane event_lineup_entries=event_lineup_entries members=members}} +
+ +
+
+
+
+
{{event.formattedTitle}}
+
{{event.gameType}}
+
+
+ + + + + + + + + {{#offenseLineup 11 event_lineup_entries members}} + + + + + + + + {{/offenseLineup }} + {{#defenseLineup event_lineup_entries members}} + + {{#if (isInPositionOnly this.member)}}{{#if (comparePositionWithFlags "P" this.eventLineupEntry)}} + + + + + + {{/if}}{{/if}} + + {{/defenseLineup}} + +
StartingSubstitution
{{this.member.lastName}}{{this.member.jerseyNumber}}{{this.label}}
PO{{this.member.lastName}}{{this.member.jerseyNumber}}{{positionLabelWithoutFlags this.eventLineupEntry.label}}
+
+
+
+
+
{{event.formattedTitle}}
+
{{event.gameType}}
+
+
+ + + + + + + + + {{#offenseLineup 11 event_lineup_entries members}} + + + + + + + + {{/offenseLineup}} + {{#defenseLineup event_lineup_entries members}} + + {{#if (isInPositionOnly this.member)}}{{#if (comparePositionWithFlags "P" this.eventLineupEntry)}} + + + + + + {{/if}}{{/if}} + + {{/defenseLineup}} + +
StartingSubstitution
{{this.member.lastName}}{{this.member.jerseyNumber}}{{this.label}}
PO{{this.member.lastName}}{{this.member.jerseyNumber}}{{positionLabelWithoutFlags this.eventLineupEntry.label}}
+
+
+
+
+
+
+
+   +
+
+   +
+
+
+
+ {{> defense_pane event_lineup_entries=null members=null}} +
+ +
+
+
+
+
+   +
+
+   +
+
+
+
+ {{> defense_pane event_lineup_entries=null members=null}} +
+ +
+
+
+
+
+ + + + + + + + + {{#repeat 12}} + + + + + + + + {{/repeat}} + +
+ Starting + + Substitution +
+ + + + +
+
+
+
+
+
+ + + + + + + + + {{!-- <% for i in (0...12) do%> --}} + {{#repeat 12}} + + + + + + + + {{/repeat}} + {{!-- <% end %> --}} + +
+ Starting + + Substitution +
+ + + + +
+
+
+
+