2023-03-04
This commit is contained in:
2
src/views/error.hbs
Normal file
2
src/views/error.hbs
Normal file
@@ -0,0 +1,2 @@
|
||||
<h1>Oops ...</h1>
|
||||
<code>{{message}}</code>
|
||||
@@ -1,8 +0,0 @@
|
||||
html
|
||||
head
|
||||
body
|
||||
h1 error
|
||||
h2
|
||||
error.status
|
||||
pre
|
||||
message #{message}
|
||||
@@ -1,409 +0,0 @@
|
||||
html
|
||||
head
|
||||
meta(charset='utf-8')
|
||||
title #{event.formattedTitle}
|
||||
link(rel='stylesheet' href='/css/gamecard.css')
|
||||
|
||||
body(class="B5")
|
||||
input(name="team_id", type="hidden" value=`${team_id}`)
|
||||
input(name="event_id", type="hidden" value=`${event_id}`)
|
||||
#page-1.sheet.gamecard
|
||||
section#todays-game
|
||||
.grid-container
|
||||
.section-header
|
||||
#todays-game-header.bar-left.event-title
|
||||
| #{event.formattedTitle}
|
||||
| #{event.startDate.toLocaleDateString("en-us",{weekday: "short", day: "numeric",month: "short"})}
|
||||
| #{event.startDate.toLocaleTimeString("en-us",{hour: "numeric", minute: "2-digit"})}
|
||||
.bar-right.homeaway #{event.gameType}
|
||||
.bar-span.gametitle
|
||||
#offense-pane.left
|
||||
table#starting-lineup-offense
|
||||
tbody
|
||||
each _, i in Array(11)
|
||||
- if (typeof(event_lineup_entries_offense[i]) !== 'undefined'){
|
||||
tr
|
||||
th(rowspan='2') #{i+1}
|
||||
td(id=`offense-slot-${i}-name` class="player-name") #{event_lineup_entries_offense[i].member.lastName}
|
||||
td(id=`offense-slot-${i}-jersey-number` class="jersey-number") #{event_lineup_entries_offense[i].member.jerseyNumber}
|
||||
td(id=`offense-slot-${i}-position` class="position") #{event_lineup_entries_offense[i].label}
|
||||
tr.substitute
|
||||
td
|
||||
td
|
||||
td
|
||||
- } else {
|
||||
tr
|
||||
th(rowspan='2')
|
||||
td(id=`offense-slot-${i}-name` class="player-name")
|
||||
td(id=`offense-slot-${i}-jersey-number` class="jersey-number")
|
||||
td(id=`offense-slot-${i}-position` class="position")
|
||||
tr.substitute
|
||||
td
|
||||
td
|
||||
td
|
||||
- }
|
||||
|
||||
#defense-pane.right
|
||||
.container
|
||||
.field-container
|
||||
image(src='/media/baseball-diamond.svg')
|
||||
.row(style='justify-content: center')
|
||||
.defense-slot-set
|
||||
table
|
||||
tr
|
||||
th.position CF
|
||||
td#defense-slot-CF-name.player-name
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("CF")) || {"member":{}}).member.lastName}
|
||||
tr
|
||||
td(colspan='2')
|
||||
tr
|
||||
td(colspan='2')
|
||||
.row(style='justify-content: space-between')
|
||||
.defense-slot-set
|
||||
table
|
||||
tr
|
||||
th.position LF
|
||||
td#defense-slot-LF-name.player-name
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("LF")) || {"member":{}}).member.lastName}
|
||||
tr
|
||||
td(colspan='2')
|
||||
tr
|
||||
td(colspan='2')
|
||||
.defense-slot-set
|
||||
table
|
||||
tr
|
||||
th.position RF
|
||||
td#defense-slot-RF-name.player-name
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("RF")) || {"member":{}}).member.lastName}
|
||||
tr
|
||||
td(colspan='2')
|
||||
tr
|
||||
td(colspan='2')
|
||||
.row(style='justify-content: space-around')
|
||||
.defense-slot-set
|
||||
table
|
||||
tr
|
||||
th.position SS
|
||||
td#defense-slot-SS-name.player-name
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("SS")) || {"member":{}}).member.lastName}
|
||||
tr
|
||||
td(colspan='2')
|
||||
tr
|
||||
td(colspan='2')
|
||||
.defense-slot-set
|
||||
table
|
||||
tr
|
||||
th.position 2B
|
||||
td#defense-slot-2B-name.player-name
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("2B")) || {"member":{}}).member.lastName}
|
||||
tr
|
||||
td(colspan='2')
|
||||
tr
|
||||
td(colspan='2')
|
||||
.row(style='justify-content: space-between')
|
||||
.defense-slot-set
|
||||
table
|
||||
tr
|
||||
th.position 3B
|
||||
td#defense-slot-3B-name.player-name
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("3B")) || {"member":{}}).member.lastName}
|
||||
tr
|
||||
td(colspan='2')
|
||||
tr
|
||||
td(colspan='2')
|
||||
.defense-slot-set
|
||||
table
|
||||
tr
|
||||
th.position 1B
|
||||
td#defense-slot-1B-name.player-name
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("1B")) || {"member":{}}).member.lastName}
|
||||
tr
|
||||
td(colspan='2')
|
||||
tr
|
||||
td(colspan='2')
|
||||
.row(style='justify-content: center')
|
||||
.defense-slot-set
|
||||
table
|
||||
tr
|
||||
th.position C
|
||||
td#defense-slot-C-name.player-name
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("C") && !lue.label.startsWith("CF") ) || {"member":{}}).member.lastName}
|
||||
tr
|
||||
td(colspan='2')
|
||||
tr
|
||||
td(colspan='2')
|
||||
.pitching-container
|
||||
.defense-slot-set
|
||||
table
|
||||
tr
|
||||
th.position P
|
||||
td#defense-slot-P-name.player-name
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("P")) || {"member":{}}).member.lastName}
|
||||
td.jersey-number
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("P")) || {"member":{}}).member.jerseyNumber}
|
||||
td.position
|
||||
tr
|
||||
th.position RP
|
||||
td#defense-slot-RP1-name.player-name
|
||||
td
|
||||
td
|
||||
tr
|
||||
th.position RP
|
||||
td#defense-slot-RP2-name.player-name
|
||||
td
|
||||
td
|
||||
.footer
|
||||
table
|
||||
tr
|
||||
th Notes
|
||||
td
|
||||
tr
|
||||
td
|
||||
tr
|
||||
td
|
||||
section#roster-and-history
|
||||
div
|
||||
table
|
||||
thead
|
||||
tr
|
||||
th#today-availability(colspan='3') Available (
|
||||
| #{availabilitySummaries.find((e)=>e.id==event_id).playerGoingCount}|
|
||||
| #{availabilitySummaries.find((e)=>e.id==event_id).playerMaybeCount}
|
||||
| )
|
||||
th.player-stats
|
||||
span.decimal-point .
|
||||
| AVG
|
||||
span.delimiter /
|
||||
span.decimal-point .
|
||||
| OBP
|
||||
span.delimiter /
|
||||
span.decimal-point .
|
||||
| SLG
|
||||
span.delimiter :
|
||||
| PA
|
||||
th.position-capability.pitcher P
|
||||
th.position-capability.catcher C
|
||||
th.position-capability.infield I
|
||||
th.position-capability.outfield O
|
||||
each event_future, i in events_future
|
||||
th(id=`avail-header-today-plus-${i+1}` class="availability future")
|
||||
.rotate #{event_future.startDate.toLocaleDateString("en-us", {weekday: "short"})}
|
||||
each event_past, i in events_past
|
||||
th(id=`avail-header-today-minus-${i+1}` class="availability past")
|
||||
.rotate #{event_past.startDate.toLocaleDateString("en-us", {weekday: "short"})}
|
||||
tbody
|
||||
each row, index in availabilities.filter((e)=>e.event.id==event_id && !e.member.isNonPlayer)
|
||||
tr(id=`roster-history-slot-${index+1}` class=``)
|
||||
td(class=`is-present-checkbox available-status-code-${row.statusCode}`)
|
||||
span ■
|
||||
td(
|
||||
class=`
|
||||
jersey-number
|
||||
border-left
|
||||
available-status-code-${row.statusCode}
|
||||
${event_lineup_entries.find((lue)=>lue.member.id==row.member.id) !== undefined ? "starting" : ""}
|
||||
`)
|
||||
| #{row.member.jerseyNumber}
|
||||
td(
|
||||
class=`
|
||||
player-name
|
||||
available-status-code-${row.statusCode}
|
||||
${event_lineup_entries.find((lue)=>lue.member.id==row.member.id) !== undefined ? "starting" : ""}
|
||||
`)
|
||||
| #{row.member.lastName}
|
||||
td.player-stats.border-left.border-right
|
||||
span.decimal-point .
|
||||
span.avg 000
|
||||
span.delimiter /
|
||||
span.decimal-point .
|
||||
span.obp 000
|
||||
span.delimiter /
|
||||
span.decimal-point .
|
||||
span.slg 000
|
||||
span.delimiter :
|
||||
span.pa 00
|
||||
td.position-capability.pitcher #{row.member.position.includes("P") ? "\u2713" : ""}
|
||||
td.position-capability.catcher #{row.member.position.includes("C") ? "\u2713" : ""}
|
||||
td.position-capability.infield #{row.member.position.includes("IF") ? "\u2713" : ""}
|
||||
td.position-capability.outfield #{row.member.position.includes("OF") ? "\u2713" : ""}
|
||||
- var future_availability
|
||||
- var future_lineupEntry
|
||||
each future_event, i in events_future
|
||||
- future_availability = availabilities.find((el)=>el.eventId ==future_event.id && el.memberId==row.member.id)
|
||||
- future_lineupEntry = all_lineup_entries.find((el)=>el.eventId ==future_event.id && el.member.id==row.member.id)
|
||||
- console.log(future_availability)
|
||||
td(id=`avail-${row.member}-today-plus-${i+1}` class=`
|
||||
row
|
||||
future
|
||||
availability
|
||||
available-status-code-${future_availability.statusCode}
|
||||
`)
|
||||
if future_lineupEntry
|
||||
|#{future_lineupEntry.label.slice(0,2)}
|
||||
else
|
||||
|#{future_availability.status[0]}
|
||||
- var past_availability
|
||||
- var past_lineupEntry
|
||||
each past_event, i in events_past
|
||||
- past_availability = availabilities.find((el)=>el.eventId==past_event.id && el.memberId==row.memberId)
|
||||
- past_lineupEntry = all_lineup_entries.find((el)=>el.event.id==past_event.id && el.member.id==row.member.id)
|
||||
td(id=`avail-${row.member}-today-minus-${i+1}` class=`
|
||||
row
|
||||
past
|
||||
availability
|
||||
available-status-code-${past_availability.statusCode}
|
||||
${past_lineupEntry ? "started" : ""}
|
||||
`)
|
||||
if past_lineupEntry
|
||||
|#{past_lineupEntry.label.slice(0,2)}
|
||||
else
|
||||
|#{past_availability.status[0]}
|
||||
tfoot
|
||||
tr
|
||||
th(colspan='3')
|
||||
th
|
||||
th(colspan='4')
|
||||
each event_future, i in events_future
|
||||
th(class=`availability future`)
|
||||
.rotate #{availabilitySummaries.find((el)=>el.eventId == event_future.id).playerGoingCount}
|
||||
th.today-minus-1
|
||||
.rotate
|
||||
th.today-minus-2
|
||||
.rotate
|
||||
th.today-minus-3
|
||||
.rotate
|
||||
th.today-minus-4
|
||||
.rotate
|
||||
section#lineup-card-dugout.lineup-card
|
||||
.grid-container
|
||||
.section-header
|
||||
.bar-left.event-title
|
||||
| #{event.formattedTitle}
|
||||
.bar-right.homeaway #{event.gameType}
|
||||
.starting-lineup-table
|
||||
table
|
||||
thead
|
||||
tr
|
||||
th(colspan='4') Starting
|
||||
tbody
|
||||
each i in [0,1,2,3,4,5,6,7,8,9,10]
|
||||
- if (typeof(event_lineup_entries_offense[i]) !== 'undefined'){
|
||||
tr
|
||||
th.sequence.label #{event_lineup_entries_offense[i].sequence +1}
|
||||
td.player-name #{event_lineup_entries_offense[i].member.lastName}
|
||||
td.jersey-number #{event_lineup_entries_offense[i].member.jerseyNumber}
|
||||
td.position #{event_lineup_entries_offense[i].label}
|
||||
- } else {
|
||||
tr
|
||||
th.sequence.label
|
||||
td.player-name
|
||||
td.jersey-number
|
||||
td.position
|
||||
tr
|
||||
td
|
||||
td
|
||||
td
|
||||
td
|
||||
- }
|
||||
|
||||
.substitution-table
|
||||
table(style='width: 100%')
|
||||
thead
|
||||
tr
|
||||
th Substitution
|
||||
tbody
|
||||
each i in [0,1,2,3,4,5,6,7,8,9,10,11]
|
||||
tr
|
||||
td.substitution
|
||||
tr
|
||||
td.substitution
|
||||
section#lineup-card-exchange.lineup-card
|
||||
.grid-container
|
||||
.section-header.event-title #{event.formattedTitleForMultiTeam}
|
||||
.starting-lineup-table
|
||||
table.starting-lineup-table
|
||||
thead
|
||||
tr
|
||||
th
|
||||
th.player-name Name
|
||||
th.jersey-number Num
|
||||
th.position Pos
|
||||
tbody
|
||||
each _,i in Array(10)
|
||||
- if (typeof(event_lineup_entries_offense[i]) !== 'undefined'){
|
||||
tr
|
||||
th.sequence.label #{event_lineup_entries_offense[i].sequence+1}
|
||||
td.player-name #{event_lineup_entries_offense[i].member.lastName}
|
||||
td.jersey-number #{event_lineup_entries_offense[i].member.jerseyNumber}
|
||||
td.position #{event_lineup_entries_offense[i].label}
|
||||
- } else {
|
||||
tr
|
||||
th.sequence.label
|
||||
td.player-name
|
||||
td.jersey-number
|
||||
td.position
|
||||
tr
|
||||
td
|
||||
td
|
||||
td
|
||||
td
|
||||
- }
|
||||
#page-2.sheet.gamecard
|
||||
section#back-cover
|
||||
section#front-cover
|
||||
div.grid-container
|
||||
.section-header
|
||||
.bar-right.homeaway #{event.gameType}
|
||||
.event-title
|
||||
| #{event.startDate.toLocaleDateString("en-us",{weekday: "long", day: "numeric",month: "short"})},
|
||||
| #{event.startDate.toLocaleTimeString("en-us",{hour: "numeric", minute: "2-digit"})}
|
||||
br
|
||||
| #{event.locationName}
|
||||
div.team
|
||||
|#{event.team.name}
|
||||
div.opponent
|
||||
|#{event.opponent.name}
|
||||
section#lineup-card-dugout-empty.lineup-card
|
||||
.grid-container
|
||||
.section-header
|
||||
.starting-lineup-table
|
||||
table
|
||||
thead
|
||||
tr
|
||||
th(colspan='4') Starting
|
||||
tbody
|
||||
each _ in Array(12)
|
||||
tr
|
||||
th.sequence.label
|
||||
td.player-name
|
||||
td.jersey-number
|
||||
td.position
|
||||
.substitution-table
|
||||
table(style='width: 100%')
|
||||
thead
|
||||
tr
|
||||
th Substitution
|
||||
tbody
|
||||
each _ in Array(11)
|
||||
tr
|
||||
td.substitution
|
||||
tr
|
||||
td.substitution
|
||||
section#lineup-card-exchange-empty.lineup-card
|
||||
.grid-container
|
||||
.section-header
|
||||
.starting-lineup-table
|
||||
table.starting-lineup-table
|
||||
thead
|
||||
tr
|
||||
th
|
||||
th.player-name Name
|
||||
th.jersey-number Num
|
||||
th.position Pos
|
||||
tbody
|
||||
each _ in Array(12)
|
||||
tr
|
||||
th.sequence.label
|
||||
td.player-name
|
||||
td.jersey-number
|
||||
td.position
|
||||
@@ -1,64 +0,0 @@
|
||||
extends base.pug
|
||||
include mixin-lineup-slot.pug
|
||||
include mixin-availability-progress-bar.pug
|
||||
|
||||
block append styles
|
||||
link(rel='stylesheet' href='/css/lineup.css')
|
||||
|
||||
block pre-scripts
|
||||
script(type='text/javascript', src='/js/Sortable.js')
|
||||
|
||||
block content
|
||||
div(id=`event-lineup-${event.id}`).event-lineup
|
||||
.Panel
|
||||
.panel-header
|
||||
.Panel-title #{event.formattedTitle}
|
||||
.Panel-body
|
||||
.Panel-row
|
||||
p.text-muted.mb-2 #{event.startDate}
|
||||
p #{event.locationName}
|
||||
+availability-progress-bar(availabilitySummary, team)
|
||||
|
||||
.Panel
|
||||
.Panel-body
|
||||
.Panel-row.Panel-title.u-padXs
|
||||
i.bi.bi-clipboard-check.me-1
|
||||
span Starting Lineup
|
||||
.Panel-row.Grid.Grid--fit.fw-bold.text-center.u-padXs
|
||||
each pos in ["P", "C", "1B", "2B", "3B", "SS", "LF", "CF", "RF", "EH", "DH"]
|
||||
.Grid-cell.position-status #{pos}
|
||||
.slot-set
|
||||
each lineup_entry, i in event_lineup_entries
|
||||
if !lineup_entry.label.includes("PO")
|
||||
+lineup-slot(lineup_entry, i)
|
||||
.Panel
|
||||
.Panel-body
|
||||
.Panel-row.Panel-title.u-padXs
|
||||
i.bi.bi-clipboard-minus.me-1
|
||||
span Starting Lineup (Position Only)
|
||||
.slot-set
|
||||
each lineup_entry, i in event_lineup_entries
|
||||
if lineup_entry.label.includes("[PO]")
|
||||
+lineup-slot(lineup_entry, i)
|
||||
.Panel
|
||||
.Panel-body
|
||||
.Panel-row.Panel-title.u-padXs
|
||||
i.bi.bi-clipboard.me-1
|
||||
span Bench
|
||||
.slot-set
|
||||
each availability, i in availabilities.filter((a)=>a.eventId==event_id && !context.event_lineup_entries.map((lue)=>lue.memberId).includes(a.memberId) && !a.member.isNonPlayer && a.statusCode!=0 && a.statusCode!==null)
|
||||
+lineup-slot(availability, i)
|
||||
|
||||
.Panel
|
||||
.Panel-body
|
||||
.Panel-row.Panel-title.u-padXs
|
||||
i.bi.bi-clipboard-x.me-1
|
||||
span Out
|
||||
.slot-set
|
||||
each availability, i in availabilities.filter((a)=>a.eventId==event_id && !context.event_lineup_entries.map((lue)=>lue.memberId).includes(a.memberId) && !a.member.isNonPlayer && (a.statusCode==0 || a.statusCode===null))
|
||||
+lineup-slot(availability, i)
|
||||
block scripts
|
||||
script
|
||||
include lineup.js
|
||||
script.
|
||||
colorPositions();
|
||||
@@ -1,409 +0,0 @@
|
||||
html
|
||||
head
|
||||
meta(charset='utf-8')
|
||||
title #{event.formattedTitle}
|
||||
link(rel='stylesheet' href='/css/gamecard.css')
|
||||
|
||||
body(class="B5")
|
||||
input(name="team_id", type="hidden" value=`${team_id}`)
|
||||
input(name="event_id", type="hidden" value=`${event_id}`)
|
||||
#page-1.sheet.gamecard
|
||||
section#todays-game
|
||||
.grid-container
|
||||
.section-header
|
||||
#todays-game-header.bar-left.event-title
|
||||
| #{event.formattedTitle}
|
||||
| #{event.startDate.toLocaleDateString("en-us",{weekday: "short", day: "numeric",month: "short"})}
|
||||
| #{event.startDate.toLocaleTimeString("en-us",{hour: "numeric", minute: "2-digit"})}
|
||||
.bar-right.homeaway #{event.gameType}
|
||||
.bar-span.gametitle
|
||||
#offense-pane.left
|
||||
table#starting-lineup-offense
|
||||
tbody
|
||||
each _, i in Array(11)
|
||||
- if (typeof(event_lineup_entries_offense[i]) !== 'undefined'){
|
||||
tr
|
||||
th(rowspan='2') #{i+1}
|
||||
td(id=`offense-slot-${i}-name` class="player-name") #{event_lineup_entries_offense[i].member.lastName}
|
||||
td(id=`offense-slot-${i}-jersey-number` class="jersey-number") #{event_lineup_entries_offense[i].member.jerseyNumber}
|
||||
td(id=`offense-slot-${i}-position` class="position") #{event_lineup_entries_offense[i].label}
|
||||
tr.substitute
|
||||
td
|
||||
td
|
||||
td
|
||||
- } else {
|
||||
tr
|
||||
th(rowspan='2')
|
||||
td(id=`offense-slot-${i}-name` class="player-name")
|
||||
td(id=`offense-slot-${i}-jersey-number` class="jersey-number")
|
||||
td(id=`offense-slot-${i}-position` class="position")
|
||||
tr.substitute
|
||||
td
|
||||
td
|
||||
td
|
||||
- }
|
||||
|
||||
#defense-pane.right
|
||||
.container
|
||||
.field-container
|
||||
image(src='/media/baseball-diamond.svg')
|
||||
.row(style='justify-content: center')
|
||||
.defense-slot-set
|
||||
table
|
||||
tr
|
||||
th.position CF
|
||||
td#defense-slot-CF-name.player-name
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("CF")) || {"member":{}}).member.lastName}
|
||||
tr
|
||||
td(colspan='2')
|
||||
tr
|
||||
td(colspan='2')
|
||||
.row(style='justify-content: space-between')
|
||||
.defense-slot-set
|
||||
table
|
||||
tr
|
||||
th.position LF
|
||||
td#defense-slot-LF-name.player-name
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("LF")) || {"member":{}}).member.lastName}
|
||||
tr
|
||||
td(colspan='2')
|
||||
tr
|
||||
td(colspan='2')
|
||||
.defense-slot-set
|
||||
table
|
||||
tr
|
||||
th.position RF
|
||||
td#defense-slot-RF-name.player-name
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("RF")) || {"member":{}}).member.lastName}
|
||||
tr
|
||||
td(colspan='2')
|
||||
tr
|
||||
td(colspan='2')
|
||||
.row(style='justify-content: space-around')
|
||||
.defense-slot-set
|
||||
table
|
||||
tr
|
||||
th.position SS
|
||||
td#defense-slot-SS-name.player-name
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("SS")) || {"member":{}}).member.lastName}
|
||||
tr
|
||||
td(colspan='2')
|
||||
tr
|
||||
td(colspan='2')
|
||||
.defense-slot-set
|
||||
table
|
||||
tr
|
||||
th.position 2B
|
||||
td#defense-slot-2B-name.player-name
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("2B")) || {"member":{}}).member.lastName}
|
||||
tr
|
||||
td(colspan='2')
|
||||
tr
|
||||
td(colspan='2')
|
||||
.row(style='justify-content: space-between')
|
||||
.defense-slot-set
|
||||
table
|
||||
tr
|
||||
th.position 3B
|
||||
td#defense-slot-3B-name.player-name
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("3B")) || {"member":{}}).member.lastName}
|
||||
tr
|
||||
td(colspan='2')
|
||||
tr
|
||||
td(colspan='2')
|
||||
.defense-slot-set
|
||||
table
|
||||
tr
|
||||
th.position 1B
|
||||
td#defense-slot-1B-name.player-name
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("1B")) || {"member":{}}).member.lastName}
|
||||
tr
|
||||
td(colspan='2')
|
||||
tr
|
||||
td(colspan='2')
|
||||
.row(style='justify-content: center')
|
||||
.defense-slot-set
|
||||
table
|
||||
tr
|
||||
th.position C
|
||||
td#defense-slot-C-name.player-name
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("C") && !lue.label.startsWith("CF") ) || {"member":{}}).member.lastName}
|
||||
tr
|
||||
td(colspan='2')
|
||||
tr
|
||||
td(colspan='2')
|
||||
.pitching-container
|
||||
.defense-slot-set
|
||||
table
|
||||
tr
|
||||
th.position P
|
||||
td#defense-slot-P-name.player-name
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("P")) || {"member":{}}).member.lastName}
|
||||
td.jersey-number
|
||||
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("P")) || {"member":{}}).member.jerseyNumber}
|
||||
td.position
|
||||
tr
|
||||
th.position RP
|
||||
td#defense-slot-RP1-name.player-name
|
||||
td
|
||||
td
|
||||
tr
|
||||
th.position RP
|
||||
td#defense-slot-RP2-name.player-name
|
||||
td
|
||||
td
|
||||
.footer
|
||||
table
|
||||
tr
|
||||
th Notes
|
||||
td
|
||||
tr
|
||||
td
|
||||
tr
|
||||
td
|
||||
section#roster-and-history
|
||||
div
|
||||
table
|
||||
thead
|
||||
tr
|
||||
th#today-availability(colspan='3') Available (
|
||||
| #{availabilitySummaries.find((e)=>e.id==event_id).playerGoingCount}|
|
||||
| #{availabilitySummaries.find((e)=>e.id==event_id).playerMaybeCount}
|
||||
| )
|
||||
th.player-stats
|
||||
span.decimal-point .
|
||||
| AVG
|
||||
span.delimiter /
|
||||
span.decimal-point .
|
||||
| OBP
|
||||
span.delimiter /
|
||||
span.decimal-point .
|
||||
| SLG
|
||||
span.delimiter :
|
||||
| PA
|
||||
th.position-capability.pitcher P
|
||||
th.position-capability.catcher C
|
||||
th.position-capability.infield I
|
||||
th.position-capability.outfield O
|
||||
each event_future, i in events_future
|
||||
th(id=`avail-header-today-plus-${i+1}` class="availability future")
|
||||
.rotate #{event_future.startDate.toLocaleDateString("en-us", {weekday: "short"})}
|
||||
each event_past, i in events_past
|
||||
th(id=`avail-header-today-minus-${i+1}` class="availability past")
|
||||
.rotate #{event_past.startDate.toLocaleDateString("en-us", {weekday: "short"})}
|
||||
tbody
|
||||
each row, index in availabilities.filter((e)=>e.event.id==event_id && !e.member.isNonPlayer)
|
||||
tr(id=`roster-history-slot-${index+1}` class=``)
|
||||
td(class=`is-present-checkbox available-status-code-${row.statusCode}`)
|
||||
span ■
|
||||
td(
|
||||
class=`
|
||||
jersey-number
|
||||
border-left
|
||||
available-status-code-${row.statusCode}
|
||||
${event_lineup_entries.find((lue)=>lue.member.id==row.member.id) !== undefined ? "starting" : ""}
|
||||
`)
|
||||
| #{row.member.jerseyNumber}
|
||||
td(
|
||||
class=`
|
||||
player-name
|
||||
available-status-code-${row.statusCode}
|
||||
${event_lineup_entries.find((lue)=>lue.member.id==row.member.id) !== undefined ? "starting" : ""}
|
||||
`)
|
||||
| #{row.member.lastName}
|
||||
td.player-stats.border-left.border-right
|
||||
span.decimal-point .
|
||||
span.avg 000
|
||||
span.delimiter /
|
||||
span.decimal-point .
|
||||
span.obp 000
|
||||
span.delimiter /
|
||||
span.decimal-point .
|
||||
span.slg 000
|
||||
span.delimiter :
|
||||
span.pa 00
|
||||
td.position-capability.pitcher #{row.member.position.includes("P") ? "\u2713" : ""}
|
||||
td.position-capability.catcher #{row.member.position.includes("C") ? "\u2713" : ""}
|
||||
td.position-capability.infield #{row.member.position.includes("IF") ? "\u2713" : ""}
|
||||
td.position-capability.outfield #{row.member.position.includes("OF") ? "\u2713" : ""}
|
||||
- var future_availability
|
||||
- var future_lineupEntry
|
||||
each future_event, i in events_future
|
||||
- future_availability = availabilities.find((el)=>el.eventId ==future_event.id && el.memberId==row.member.id)
|
||||
- future_lineupEntry = all_lineup_entries.find((el)=>el.eventId ==future_event.id && el.member.id==row.member.id)
|
||||
- console.log(future_availability)
|
||||
td(id=`avail-${row.member}-today-plus-${i+1}` class=`
|
||||
row
|
||||
future
|
||||
availability
|
||||
available-status-code-${future_availability.statusCode}
|
||||
`)
|
||||
if future_lineupEntry
|
||||
|#{future_lineupEntry.label.slice(0,2)}
|
||||
else
|
||||
|#{future_availability.status[0]}
|
||||
- var past_availability
|
||||
- var past_lineupEntry
|
||||
each past_event, i in events_past
|
||||
- past_availability = availabilities.find((el)=>el.eventId==past_event.id && el.memberId==row.memberId)
|
||||
- past_lineupEntry = all_lineup_entries.find((el)=>el.event.id==past_event.id && el.member.id==row.member.id)
|
||||
td(id=`avail-${row.member}-today-minus-${i+1}` class=`
|
||||
row
|
||||
past
|
||||
availability
|
||||
available-status-code-${past_availability.statusCode}
|
||||
${past_lineupEntry ? "started" : ""}
|
||||
`)
|
||||
if past_lineupEntry
|
||||
|#{past_lineupEntry.label.slice(0,2)}
|
||||
else
|
||||
|#{past_availability.status[0]}
|
||||
tfoot
|
||||
tr
|
||||
th(colspan='3')
|
||||
th
|
||||
th(colspan='4')
|
||||
each event_future, i in events_future
|
||||
th(class=`availability future`)
|
||||
.rotate #{availabilitySummaries.find((el)=>el.eventId == event_future.id).playerGoingCount}
|
||||
th.today-minus-1
|
||||
.rotate
|
||||
th.today-minus-2
|
||||
.rotate
|
||||
th.today-minus-3
|
||||
.rotate
|
||||
th.today-minus-4
|
||||
.rotate
|
||||
section#lineup-card-dugout.lineup-card
|
||||
.grid-container
|
||||
.section-header
|
||||
.bar-left.event-title
|
||||
| #{event.formattedTitle}
|
||||
.bar-right.homeaway #{event.gameType}
|
||||
.starting-lineup-table
|
||||
table
|
||||
thead
|
||||
tr
|
||||
th(colspan='4') Starting
|
||||
tbody
|
||||
each i in [0,1,2,3,4,5,6,7,8,9,10]
|
||||
- if (typeof(event_lineup_entries_offense[i]) !== 'undefined'){
|
||||
tr
|
||||
th.sequence.label #{event_lineup_entries_offense[i].sequence +1}
|
||||
td.player-name #{event_lineup_entries_offense[i].member.lastName}
|
||||
td.jersey-number #{event_lineup_entries_offense[i].member.jerseyNumber}
|
||||
td.position #{event_lineup_entries_offense[i].label}
|
||||
- } else {
|
||||
tr
|
||||
th.sequence.label
|
||||
td.player-name
|
||||
td.jersey-number
|
||||
td.position
|
||||
tr
|
||||
td
|
||||
td
|
||||
td
|
||||
td
|
||||
- }
|
||||
|
||||
.substitution-table
|
||||
table(style='width: 100%')
|
||||
thead
|
||||
tr
|
||||
th Substitution
|
||||
tbody
|
||||
each i in [0,1,2,3,4,5,6,7,8,9,10,11]
|
||||
tr
|
||||
td.substitution
|
||||
tr
|
||||
td.substitution
|
||||
section#lineup-card-exchange.lineup-card
|
||||
.grid-container
|
||||
.section-header.event-title #{event.formattedTitleForMultiTeam}
|
||||
.starting-lineup-table
|
||||
table.starting-lineup-table
|
||||
thead
|
||||
tr
|
||||
th
|
||||
th.player-name Name
|
||||
th.jersey-number Num
|
||||
th.position Pos
|
||||
tbody
|
||||
each _,i in Array(10)
|
||||
- if (typeof(event_lineup_entries_offense[i]) !== 'undefined'){
|
||||
tr
|
||||
th.sequence.label #{event_lineup_entries_offense[i].sequence+1}
|
||||
td.player-name #{event_lineup_entries_offense[i].member.lastName}
|
||||
td.jersey-number #{event_lineup_entries_offense[i].member.jerseyNumber}
|
||||
td.position #{event_lineup_entries_offense[i].label}
|
||||
- } else {
|
||||
tr
|
||||
th.sequence.label
|
||||
td.player-name
|
||||
td.jersey-number
|
||||
td.position
|
||||
tr
|
||||
td
|
||||
td
|
||||
td
|
||||
td
|
||||
- }
|
||||
#page-2.sheet.gamecard
|
||||
section#back-cover
|
||||
section#front-cover
|
||||
div.grid-container
|
||||
.section-header
|
||||
.bar-right.homeaway #{event.gameType}
|
||||
.event-title
|
||||
| #{event.startDate.toLocaleDateString("en-us",{weekday: "long", day: "numeric",month: "short"})},
|
||||
| #{event.startDate.toLocaleTimeString("en-us",{hour: "numeric", minute: "2-digit"})}
|
||||
br
|
||||
| #{event.locationName}
|
||||
div.team
|
||||
|#{event.team.name}
|
||||
div.opponent
|
||||
|#{event.opponent.name}
|
||||
section#lineup-card-dugout-empty.lineup-card
|
||||
.grid-container
|
||||
.section-header
|
||||
.starting-lineup-table
|
||||
table
|
||||
thead
|
||||
tr
|
||||
th(colspan='4') Starting
|
||||
tbody
|
||||
each _ in Array(12)
|
||||
tr
|
||||
th.sequence.label
|
||||
td.player-name
|
||||
td.jersey-number
|
||||
td.position
|
||||
.substitution-table
|
||||
table(style='width: 100%')
|
||||
thead
|
||||
tr
|
||||
th Substitution
|
||||
tbody
|
||||
each _ in Array(11)
|
||||
tr
|
||||
td.substitution
|
||||
tr
|
||||
td.substitution
|
||||
section#lineup-card-exchange-empty.lineup-card
|
||||
.grid-container
|
||||
.section-header
|
||||
.starting-lineup-table
|
||||
table.starting-lineup-table
|
||||
thead
|
||||
tr
|
||||
th
|
||||
th.player-name Name
|
||||
th.jersey-number Num
|
||||
th.position Pos
|
||||
tbody
|
||||
each _ in Array(12)
|
||||
tr
|
||||
th.sequence.label
|
||||
td.player-name
|
||||
td.jersey-number
|
||||
td.position
|
||||
@@ -1,27 +0,0 @@
|
||||
extends base.pug
|
||||
include mixin-availability-progress-bar.pug
|
||||
|
||||
block content
|
||||
.Panel
|
||||
.Panel-header
|
||||
h3.Panel-title #{event.formattedTitle}
|
||||
.Panel-body
|
||||
.Panel-row
|
||||
h6.card-text.text-muted.mb-2
|
||||
|#{event.startDate}
|
||||
br
|
||||
|#{event.locationName}
|
||||
.Panel-row
|
||||
h4 Availability
|
||||
+availability-progress-bar(availabilitySummary, team)
|
||||
.Panel-row
|
||||
div.d-flex
|
||||
a(class="Button m-auto" href=`/${team_id}/event/${event.id}/lineup`)
|
||||
i(class="bi bi-clipboard")
|
||||
span.mx-1 Lineup
|
||||
a(class="Button m-auto" href=`/${team_id}/event/${event.id}/lineup_card`)
|
||||
i(class="bi bi-book")
|
||||
span.mx-1 Game Card
|
||||
a(class="Button m-auto" href=`https://go.teamsnap.com/${team_id}/schedule/view_game/${event.id}`)
|
||||
i(class="bi bi-asterisk")
|
||||
span.mx-1 TeamSnap
|
||||
120
src/views/event/list.hbs
Normal file
120
src/views/event/list.hbs
Normal file
@@ -0,0 +1,120 @@
|
||||
<h1>
|
||||
Schedule
|
||||
</h1>
|
||||
<div class="Panel">
|
||||
<div class="Panel-body">
|
||||
<div class="Panel-row Panel-row--withCells u-textDecorationNone">
|
||||
<div class="Panel-cell u-size7of24 u-textLeft">
|
||||
<h4 class="Panel-title">
|
||||
Title
|
||||
</h4>
|
||||
</div>
|
||||
<div class="Panel-cell u-size3of24 u-hidden u-xs-block">
|
||||
<h4 class="Panel-title">
|
||||
Date
|
||||
</h4>
|
||||
</div>
|
||||
<div class="Panel-cell u-size3of24 u-hidden u-xs-block">
|
||||
<h4 class="Panel-title">
|
||||
Time
|
||||
</h4>
|
||||
</div>
|
||||
<div class="Panel-cell u-size3of24 u-xs-hidden">
|
||||
<h4 class="Panel-title">
|
||||
When/Where
|
||||
</h4>
|
||||
</div>
|
||||
<div class="Panel-cell u-size7of24 u-hidden u-xs-block">
|
||||
<h4 class="Panel-title">
|
||||
Location
|
||||
</h4>
|
||||
</div>
|
||||
<div class="Panel-cell u-size3of24 u-borderLeft">
|
||||
<h4 class="Panel-title">
|
||||
...
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
{{#each events as |event|}}
|
||||
<div class="Panel-row Panel-row--withCells">
|
||||
<div class="Panel-cell u-size7of24 u-textLeft">
|
||||
<a href="event/{{this.id}}">
|
||||
{{event.formattedTitle}}
|
||||
</a>
|
||||
</div>
|
||||
<div class="Panel-cell u-size3of24 u-textLeft u-hidden u-xs-block">
|
||||
{{dateFormat event.startDate "ddd MMM D"}}
|
||||
</div>
|
||||
<div class="Panel-cell u-size3of24 u-hidden u-xs-block">
|
||||
{{dateFormat event.startDate "h:mm A"}}
|
||||
</div>
|
||||
<div class="Panel-cell u-size3of24 u-xs-hidden">
|
||||
{{dateFormat this.startDate "ddd MMM D, h:mm A"}} {{
|
||||
event.locationName
|
||||
}}
|
||||
</div>
|
||||
<div class="Panel-cell u-size7of24 u-hidden u-xs-block">
|
||||
{{event.locationName}}
|
||||
</div>
|
||||
<div class="Panel-cell u-size3of24 u-borderLeft">
|
||||
<button
|
||||
class="Button Button--small Button--default Popup"
|
||||
onclick='console.log(this);this.querySelector(".Popup-container").classList.toggle("is-open")'
|
||||
;
|
||||
>
|
||||
...
|
||||
<div
|
||||
class="Popup-container Popup-container--up Popup-container--right"
|
||||
>
|
||||
<div class="Popup-content u-textDecorationNone">
|
||||
<div class="Grid Grid--fit u-spaceXs">
|
||||
<div class="Grid-cell u-sizeFit u-spaceXs">
|
||||
<a href="url_for(event_path :team_id=>team.id, :event_id=>event.id)">
|
||||
<span>{{{embeddedSvgFromPath "/bootstrap-icons/calendar.svg"}}}</span>
|
||||
<span class="u-hidden u-xs-inline">Details</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="Grid-cell u-sizeFit u-spaceXs">
|
||||
<a href="/{{team.id}}/event/{{event.id}}/lineup">
|
||||
<span>{{{embeddedSvgFromPath "/bootstrap-icons/clipboard.svg"}}}</span>
|
||||
<span class="u-hidden u-xs-inline">Lineup</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="Grid-cell u-sizeFit u-spaceXs">
|
||||
<a href="/{{team.id}}/event/{{event.id}}/sheet">
|
||||
<span>{{{embeddedSvgFromPath "/bootstrap-icons/file-earmark.svg"}}}</span>
|
||||
<span class="u-hidden u-xs-inline">Sheet</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="Grid-cell u-sizeFit u-spaceXs">
|
||||
<a href="https://go.teamsnap.com/{{../team.id}}/schedule/view_game/{{event.id}}">
|
||||
<span>{{{embeddedSvgFromPath "/media/teamsnap_star.svg"}}}</span>
|
||||
<span class="u-hidden u-xs-inline">TeamSnap</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{!--
|
||||
|
||||
a.Button href=url_for(event_path :team_id=>team.id, :event_id=>event.id)
|
||||
=embedded_svg "teamsnap-ui/assets/icons/schedule svg", class:"Icon"
|
||||
| Details
|
||||
.Grid-cell.u-sizeFit.u-spaceXs
|
||||
a.Button href=url_for(event_lineup_path :team_id => team.id, :event_id => event.id)
|
||||
=embedded_svg "bootstrap-icons/clipboard svg", class:"Icon"
|
||||
| Lineup
|
||||
.Grid-cell.u-sizeFit.u-spaceXs
|
||||
a.Button href=url_for(event_lineup_card_path :team_id => team.id, :event_id => event.id)
|
||||
=embedded_svg "bootstrap-icons/book svg", class:"Icon"
|
||||
| Card
|
||||
.Grid-cell.u-sizeFit.u-spaceXs
|
||||
a.Button href="https://go teamsnap com/#{team id}/schedule/view_game/#{event id}"
|
||||
=embedded_svg "bootstrap-icons/asterisk svg", class:"Icon"
|
||||
| TeamSnap }} --}}
|
||||
</div>
|
||||
</div>
|
||||
16
src/views/event/partials/availability_bar.hbs
Normal file
16
src/views/event/partials/availability_bar.hbs
Normal file
@@ -0,0 +1,16 @@
|
||||
<div class="progress">
|
||||
{{#if availabilitySummary}}
|
||||
<div class="progress-bar availability-bar going" role="progressbar" style="width:{{availability_percentage availabilitySummary "going"}}%">
|
||||
{{availabilitySummary.playerGoingCount}}
|
||||
</div>
|
||||
<div class="progress-bar availability-bar maybe" role="progressbar" style="width:{{availability_percentage availabilitySummary "maybe"}}%">
|
||||
{{availabilitySummary.playerMaybeCount}}
|
||||
</div>
|
||||
<div class="progress-bar availability-bar not-going" role="progressbar" style="width:{{availability_percentage availabilitySummary "notgoing"}}%">
|
||||
{{availabilitySummary.playerNotGoingCount}}
|
||||
</div>
|
||||
<div class="progress-bar availability-bar unknown" role="progressbar" style="width:{{availability_percentage availabilitySummary "unknown"}}%">
|
||||
{{availabilitySummary.playerUnknownCount}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
32
src/views/event/partials/event_panel.hbs
Normal file
32
src/views/event/partials/event_panel.hbs
Normal file
@@ -0,0 +1,32 @@
|
||||
<div class="Panel">
|
||||
<div class="Panel-header u-padEndsSm">
|
||||
<h3><a href="/{{team.id}}/event/{{event.id}}">{{event.formattedTitle}}</a></h3>
|
||||
</div>
|
||||
<div class=" Panel-body u-padEndsSm">
|
||||
<div class=" u-padSidesSm">
|
||||
<div class="date" >{{dateFormat event.startDate "ddd, MMM D h:mm A" }}</div>
|
||||
<div class="location">{{event.locationName}}</div>
|
||||
</div>
|
||||
<div class=" availability-bar fullwidth">
|
||||
{{> availability_bar availabilitySummary=event.availabilitySummary}}
|
||||
</div>
|
||||
</div>
|
||||
<div class=" Panel-footer u-flex u-flexJustifyAround u-padSm">
|
||||
<a class="Button" href="/{{team.id}}/event/{{event.id}}">
|
||||
<span>{{{embeddedSvgFromPath "/bootstrap-icons/calendar.svg"}}}</span>
|
||||
<span class="u-hidden u-xs-inline">Details</span>
|
||||
</a>
|
||||
<a class="Button" href="/{{team.id}}/event/{{event.id}}/lineup">
|
||||
<span>{{{embeddedSvgFromPath "/bootstrap-icons/clipboard.svg"}}}</span>
|
||||
<span class="u-hidden u-xs-inline">Lineup</span>
|
||||
</a>
|
||||
<a class="Button" href="/{{team.id}}/event/{{event.id}}/sheet">
|
||||
<span>{{{embeddedSvgFromPath "/bootstrap-icons/file-earmark.svg"}}}</span>
|
||||
<span class="u-hidden u-xs-inline">Sheet</span>
|
||||
</a>
|
||||
<a class="Button" href="https://go.teamsnap.com/{{team.id}}/schedule/view_game/{{event.id}}">
|
||||
<span>{{{embeddedSvgFromPath "/media/teamsnap_star.svg"}}}</span>
|
||||
<span class="u-hidden u-xs-inline">TeamSnap</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
1
src/views/event/show.hbs
Normal file
1
src/views/event/show.hbs
Normal file
@@ -0,0 +1 @@
|
||||
{{> event_panel event=event}}
|
||||
120
src/views/eventlineup/edit.hbs
Normal file
120
src/views/eventlineup/edit.hbs
Normal file
@@ -0,0 +1,120 @@
|
||||
{{>emailmodal}}
|
||||
<div id="event-lineup-{{event.id}}" data-event-lineup-id="{{event_lineup.id}}" data-event-id="{{event.id}}">
|
||||
<form onsubmit="onSubmit(this,event)" action="#">
|
||||
<input type="hidden" name="event_lineup_id" value="{{event_lineup.id}}">
|
||||
{{!-- <input type="hidden" name="_csrf" value="{{csrfToken}}"> --}}
|
||||
<input type="hidden" name="csrfToken" value="{{csrfToken}}">
|
||||
<div class="Panel Panel--full">
|
||||
<div class="Panel-header u-padEndsSm">
|
||||
<h3 style="flex: 1 1 0%;">{{event.formattedTitle}}</h3>
|
||||
<div class="ButtonGroup">
|
||||
<button class="Button Button--orange" type="submit" formmethod="post">
|
||||
<div>
|
||||
<span id="teamsnap-icon">{{{embeddedSvgFromPath "/media/teamsnap_star.svg"}}}</span>
|
||||
<span id="waiting-icon" class="u-hidden">{{{embeddedSvgFromPath "/teamsnap-ui/assets/icons/loader.svg" "Icon--loader"}}}</span>
|
||||
<span id="success-icon" class="u-hidden">{{{embeddedSvgFromPath "/teamsnap-ui/assets/icons/check.svg"}}}</span>
|
||||
<span id="failure-icon" class="u-hidden">{{{embeddedSvgFromPath "/teamsnap-ui/assets/icons/dismiss.svg"}}}</span>
|
||||
Save
|
||||
</div>
|
||||
</button>
|
||||
<div class="Button Button--orange .u-padSidesXs Popup" onclick="togglePopup(this)">
|
||||
{{{embeddedSvgFromPath "/teamsnap-ui/assets/icons/caret-down.svg"}}}
|
||||
<div class="Popup-container Popup-container--down Popup-container--right" style="width: 200px">
|
||||
<div class="Popup-content u-textDecorationNone">
|
||||
<a class="u-padEndsSm u-padSidesMd u-textDecorationNone" href="javascript:void(0)" onclick="emailModal(this, '{{event_lineup.id}}/email')">
|
||||
{{{embeddedSvgFromPath "/bootstrap-icons/envelope.svg"}}}
|
||||
<span>Generate Email</span>
|
||||
</a>
|
||||
<hr class="Divider u-spaceEndsNone">
|
||||
<a class="u-padEndsSm u-padSidesMd u-textDecorationNone" href="../sheet">
|
||||
{{{embeddedSvgFromPath "/bootstrap-icons/book.svg"}}}
|
||||
<span>Lineup Card</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" Panel-body u-padEndsSm">
|
||||
<div class=" u-padSidesSm">
|
||||
<div class="date">{{dateFormat event.startDate "ddd, MMM D h:mm A" }}</div>
|
||||
<div class="location">{{event.locationName}}</div>
|
||||
</div>
|
||||
<div class=" availability-bar fullwidth">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="lineup-starting-{{event.id}}" class="Panel u-maxWidthSm starting Panel--fullWidthMobile Panel--full">
|
||||
<div class="Panel-body">
|
||||
<div class="Panel-row Panel-title u-padXs">
|
||||
<i>{{{embeddedSvgFromPath "/bootstrap-icons/clipboard-check.svg"}}}</i>
|
||||
<span>Starting Lineup</span>
|
||||
</div>
|
||||
<div class=" Panel-row Grid Grid--fit u-textBold u-textCenter u-padXs">
|
||||
{{#each (positions)}}
|
||||
<div class="Grid-cell position-status">{{this}}</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="slot-set">
|
||||
{{#each members}}
|
||||
{{#if (isInStartingLineup this)}}
|
||||
{{> slot member=this}}
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="lineup-positiononly-{{event.id}}" class="Panel u-maxWidthSm position-only Panel--full">
|
||||
<div class="Panel-row Panel-title u-padXs">
|
||||
{{{embeddedSvgFromPath "/bootstrap-icons/clipboard-check.svg"}}}
|
||||
<span>Position Only</span>
|
||||
</div>
|
||||
<div class="slot-set">
|
||||
{{#each members}}
|
||||
{{#if (isInPositionOnly this)}}
|
||||
{{> slot member=this}}
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
<div id="lineup-bench-{{event.id}}" class="Panel u-maxWidthSm bench Panel--full">
|
||||
<div class="Panel-row Panel-title u-padXs">
|
||||
{{{embeddedSvgFromPath "/bootstrap-icons/clipboard-minus.svg"}}}
|
||||
<span>Bench</span>
|
||||
</div>
|
||||
<div class="slot-set">
|
||||
{{#each members}}
|
||||
{{#if (isInBench this)}}
|
||||
{{> slot member=this event=../event}}
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
<div id="lineup-out-{{event.id}}" class="Panel u-maxWidthSm out Panel--full">
|
||||
<div class="Panel-row Panel-title u-padXs">
|
||||
<span style="flex: 1 1 0%;">{{{embeddedSvgFromPath "/bootstrap-icons/clipboard-x.svg"}}}Out</span>
|
||||
<div class="Toggle">
|
||||
<input class="Toggle-input" type="checkbox" id="enable-slots" onclick="toggleChildSlots(this);">
|
||||
<label class="Toggle-label" for="availability-tab"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="slot-set">
|
||||
{{#each members}}
|
||||
{{#if (isInOut this)}}
|
||||
{{> slot member=this}}
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
|
||||
<script src="/js/eventlineup.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
colorPositions();
|
||||
refreshLineupOrder();
|
||||
})
|
||||
</script>
|
||||
|
||||
90
src/views/eventlineup/email.hbs
Normal file
90
src/views/eventlineup/email.hbs
Normal file
@@ -0,0 +1,90 @@
|
||||
<div class="lineup-email">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="title-cell" colSpan=3>
|
||||
STARTING LINEUP
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each members}}
|
||||
{{#if (isInStartingLineup this)}}
|
||||
<tr>
|
||||
<td class="sequence-cell">
|
||||
{{plus1 this.benchcoach.eventLineupEntry.sequence}}
|
||||
</td>
|
||||
<td class="name-cell">{{this.lastName}}, {{this.firstName}} – #{{this.jerseyNumber}}</td>
|
||||
<td class="position-label-cell">{{this.benchcoach.eventLineupEntry.label}}</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
<tr>
|
||||
<th class="title-cell" colSpan=3>Starting (Pos. Only)</th>
|
||||
</tr>
|
||||
{{#each members}}
|
||||
{{#if (isInPositionOnly this)}}
|
||||
<tr>
|
||||
<td class="sequence-cell"></td>
|
||||
<td class="name-cell">{{this.lastName}}, {{this.firstName}} – #{{this.jerseyNumber}}</td>
|
||||
<td class="position-label-cell">{{this.benchcoach.eventLineupEntry.label}}</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
<tr>
|
||||
<th class="title-cell" colSpan=3>Subs</th>
|
||||
</tr>
|
||||
{{#each members}}
|
||||
{{#if (isInBench this)}}
|
||||
<tr>
|
||||
<td class="sequence-cell">
|
||||
{{availabilityStatusShort this.benchcoach.availability}}
|
||||
</td>
|
||||
<td class="name-cell">{{this.lastName}}, {{this.firstName}} – #{{this.jerseyNumber}}</td>
|
||||
<td class="position-label-cell">{{this.benchcoach.eventLineupEntry.label}}</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
<tr>
|
||||
<th class="title-cell out" colSpan=3>Out</th>
|
||||
</tr>
|
||||
{{#each members}}
|
||||
{{#if (isInOut this)}}
|
||||
<tr>
|
||||
<td class="sequence-cell">
|
||||
{{availabilityStatusShort this.benchcoach.availability}}
|
||||
</td>
|
||||
<td class="name-cell">{{this.lastName}}, {{this.firstName}} – #{{this.jerseyNumber}}</td>
|
||||
<td class="position-label-cell">{{this.benchcoach.eventLineupEntry.label}}</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
{{!-- <tr>
|
||||
|
||||
<tr>
|
||||
<th>.title-cell colSpan=3 Subs
|
||||
- for entry in event_lineup_entries.select{|e| e[:label].blank? and !(e[:availability_status_code] == "0" or e[:availability_status_code]== "")}
|
||||
<tr>
|
||||
<td>.sequence-cell
|
||||
- if entry[:availability_status_code] == "1"
|
||||
| YES
|
||||
- if entry[:availability_status_code] == "2"
|
||||
| MAY
|
||||
<td>.name-cell
|
||||
| #{entry[:member][:last_name]}, #{entry[:member][:first_name]} - ##{entry[:member][:jersey_number]}
|
||||
<td>
|
||||
<tr>
|
||||
<th>.title-cell.out colSpan=3 Out
|
||||
- for entry in event_lineup_entries.select{|e| e[:label].blank? and (e[:availability_status_code] == "0" or e[:availability_status_code]== "")}
|
||||
<tr>
|
||||
<td>.sequence-cell
|
||||
- if entry[:availability_status_code] == "0"
|
||||
| NO
|
||||
- if entry[:availability_status_code] == ""
|
||||
| UNK
|
||||
<td>.name-cell
|
||||
| #{entry[:member][:last_name]}, #{entry[:member][:first_name]} - ##{entry[:member][:jersey_number]}
|
||||
<td> --}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
16
src/views/eventlineup/partials/emailmodal.hbs
Normal file
16
src/views/eventlineup/partials/emailmodal.hbs
Normal file
@@ -0,0 +1,16 @@
|
||||
<div id="modal" class="Modal Modal--clickableBg">
|
||||
<div class="Modal-bgDismiss" onclick="javascript:this.closest('.Modal').classList.toggle('is-open')"></div>
|
||||
<div class="Modal-content">
|
||||
<div onclick="javascript:this.closest('.Modal').classList.toggle('is-open')">{{{embeddedSvgFromPath "/teamsnap-ui/assets/icons/dismiss.svg" "Modal-iconDismiss"}}}</div>
|
||||
<div class="Modal-header">
|
||||
<div class="Modal-title">Email</div>
|
||||
<div class="ButtonGroup">
|
||||
<div class="Button" role="button" onclick="javascript:range=document.createRange();window.getSelection().removeAllRanges();range.selectNode(document.querySelector('.Modal').querySelector('.Modal-body')); window.getSelection().addRange(range);document.execCommand('copy');window.getSelection().removeAllRanges();">
|
||||
{{{embeddedSvgFromPath "/bootstrap-icons/clipboard.svg"}}}
|
||||
Copy to clipboard
|
||||
</div>
|
||||
</div>
|
||||
<div class="Modal-body"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
57
src/views/eventlineup/partials/slot.hbs
Normal file
57
src/views/eventlineup/partials/slot.hbs
Normal file
@@ -0,0 +1,57 @@
|
||||
<div class="Panel-expandableRow lineup-slot">
|
||||
<input type="hidden" name="label" value="{{member.benchcoach.eventLineupEntry.label}}">
|
||||
<input type="hidden" name="sequence" value="{{member.benchcoach.eventLineupEntry.sequence}}">
|
||||
<input type="hidden" name="eventId" value="{{event.id}}">
|
||||
<input type="hidden" name="eventLineupEntryId" value="{{member.benchcoach.eventLineupEntry.id}}">
|
||||
<input type="hidden" name="availabilityStatusCode", value="{{member.benchcoach.availability?.statusCode}}">
|
||||
<input type="hidden" name="memberId" value="{{member.id}}">
|
||||
<input type="hidden" name="lastName" value="{{member.lastName}}">
|
||||
<input type="hidden" name="firstName" value="{{member.firstName}}">
|
||||
<input type="hidden" name="jerseyNumber" value="{{member.jerseyNumber}}">
|
||||
<input type="hidden" name="emailAddresses" value="{{member.emailAddresses}}">
|
||||
<div class="Panel-row Panel-row--withCells Panel-row--parent">
|
||||
<div
|
||||
class="Panel-cell Panel-cell--header">
|
||||
<div class="sequence u-textNoWrap u-fontSizeLg"></div>
|
||||
</div>
|
||||
<div class="Panel-cell u-padXs u-sizeFill">
|
||||
<div
|
||||
class="d-flex availability-status-code-{{
|
||||
member.benchcoach.availability?.statusCode
|
||||
}}"
|
||||
>
|
||||
<div class="u-flexInline u-fontSizeLg u-textNoWrap">
|
||||
{{#if member.benchcoach.availability}}{{{avail_status_code_icon member.benchcoach.availability.statusCode}}}{{/if}}
|
||||
<span class="lastname">
|
||||
{{member.lastName}}
|
||||
</span>
|
||||
<span class="lastname u-hidden u-sm-inline">
|
||||
, {{member.firstName}}
|
||||
</span>
|
||||
<span class="jerseynumber u-hidden u-sm-inline u-fontSizeSm">
|
||||
#{{member.jerseyNumber}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="Panel-cell u-padXs u-sizeFit">
|
||||
<div class="SelectBox position-selection">
|
||||
<select name="positionLabelSelectBox" class="position-select-box SelectBox-options" onchange="onPositionSelectChange(this)" >
|
||||
<option value="--">
|
||||
--
|
||||
</option>
|
||||
{{#each (positions)}}
|
||||
<option value="{{this}}" {{#if (comparePositionWithFlags this ../member.benchcoach.eventLineupEntry)}}selected{{/if}}>
|
||||
{{this}}
|
||||
</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="Panel-cell u-padSidesMd u-sizeFit">
|
||||
<div class="drag-handle">
|
||||
{{{embeddedSvgFromPath "/bootstrap-icons/grip-vertical.svg"}}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
0
src/views/eventlineup/show.hbs
Normal file
0
src/views/eventlineup/show.hbs
Normal file
@@ -1,21 +0,0 @@
|
||||
extends base.pug
|
||||
include mixin-availability-progress-bar.pug
|
||||
|
||||
block content
|
||||
.Panel
|
||||
.Panel-header
|
||||
.Panel-title Schedule
|
||||
.Panel-body
|
||||
each event in events
|
||||
- var availabilitySummary = availabilitySummaries.find((a)=>a.eventId==event.id)
|
||||
a(class="event list-group-item" href=`/${team_id}/event/${event.id}`).Panel-row--withCells
|
||||
.Panel-cell
|
||||
h4 #{event.formattedTitle}
|
||||
+availability-progress-bar(availabilitySummary, team)
|
||||
.Panel-cell
|
||||
|#{event.startDate.toLocaleDateString("en-us",{weekday: "short", day: "numeric",month: "short"})}
|
||||
.Panel-cell
|
||||
|#{event.startDate.toLocaleTimeString("en-us",{hour: "numeric", minute: "2-digit"})}
|
||||
.Panel-cell
|
||||
|#{event.locationName}
|
||||
|
||||
352
src/views/eventsheet/sheet.hbs
Normal file
352
src/views/eventsheet/sheet.hbs
Normal file
@@ -0,0 +1,352 @@
|
||||
<link rel="stylesheet" href="/css/eventsheet.css">
|
||||
|
||||
<body class="B5">
|
||||
<div class="sheet eventsheet" id="page-1">
|
||||
<section id="todays-game">
|
||||
<header>
|
||||
<div class="event-title float-left">
|
||||
{{event.formattedTitle}} – {{dateFormat event.startDate "ddd, MMM D h:mm A" }}
|
||||
</div>
|
||||
<div class="homeaway float-right">
|
||||
{{event.game_type}}
|
||||
</div>
|
||||
</header>
|
||||
<div class="grid-container">
|
||||
<div id="offense-pane">
|
||||
<table id="starting-lineup-offense">
|
||||
<tbody>
|
||||
<div class="slot-set">
|
||||
{{!-- <% offensive_lineup_entries = by_member.select{|m,d| d[:event_lineup_entry] and d[:event_lineup_entry].label.exclude?("[PO]")}.sort_by{|m,d| d[:event_lineup_entry].sequence}.each_with_index do |(member, d), i| if i < 11%> --}}
|
||||
{{#offenseLineup 11}}
|
||||
<tr class="slot">
|
||||
<th class="sequence counter" rowspan="2"></th>
|
||||
<td class="player-name">{{this.member.lastName}}</td>
|
||||
<td class="jersey-number">{{this.member.jerseyNumber}}</td>
|
||||
<td class="position">{{positionLabelWithoutFlags this.label}}</td>
|
||||
</tr>
|
||||
<tr class="slot substitute">
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
{{/offenseLineup}}
|
||||
</div>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="defense-pane">
|
||||
<div class="field-container">
|
||||
<img src="/media/baseball-diamond.svg" />
|
||||
{{#defenseLineup}}
|
||||
{{!-- <% for pos in ["CF", "LF", "RF", "SS", "2B", "3B", "1B", "C"] do (member, d) = by_member.find{|m,d| d[:event_lineup_entry] and d[:event_lineup_entry].label == pos}%> --}}
|
||||
<div class="slot-set pos-{{this.position}}">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr class="slot">
|
||||
<th class="position"></th>
|
||||
<td class="player-name">{{this.member.lastName}}</td>
|
||||
</tr>
|
||||
<tr class="slot substitute">
|
||||
<th class="position"></th>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="slot substitute">
|
||||
<th class="position"></th><td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{/defenseLineup}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<table class="notes">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Notes</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="roster-and-history">
|
||||
<div>
|
||||
<table>
|
||||
<colgroup><col span="3" class="player"></colgroup>
|
||||
{{!-- <colgroup><col span="0" class="player-stats"></colgroup> --}}
|
||||
<colgroup><col span="4" class="position-capability"></colgroup>
|
||||
<colgroup><col span="4" class="availability-on-day future"></colgroup>
|
||||
<colgroup><col span="4" class="availability-on-day past"></colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="3" id="today-availability">
|
||||
Available ({{availabilitySummary.playerGoingCount}}|{{availabilitySummary.playerMaybeCount}})
|
||||
</th>
|
||||
<th class="player-stats">
|
||||
<span class="decimal-point">.</span>AVG
|
||||
<span class="delimiter">/</span>
|
||||
<span class="decimal-point">.</span>OBP
|
||||
<span class="delimiter">/</span>
|
||||
<span class="decimal-point">.</span>SLG
|
||||
<span class="delimiter">:</span>PA
|
||||
</th>
|
||||
<th class="position-capability pitcher">P</th>
|
||||
<th class="position-capability catcher">C</th>
|
||||
<th class="position-capability infield">I</th>
|
||||
<th class="position-capability outfield">O</th>
|
||||
{{!-- <% 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}}
|
||||
<th class="availability-on-day avail-today-plus-{{@index}}" date="{{this.startDate}}"><div>{{dateFormat this.startDate "ddd" }}</div></th>
|
||||
{{/loopEvents}}
|
||||
{{#loopEvents recent_events}}
|
||||
<th class="availability-on-day avail-today-minus-{{@index}}" date="{{this.startDate}}"><div>{{dateFormat this.startDate "ddd" }}</div></th>
|
||||
{{/loopEvents}}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{!-- <% by_member.select{|m,d| !m.is_non_player}.each_with_index do |(member, d), i|%> --}}
|
||||
{{#rosterHistory}}
|
||||
<tr id="roster-history-slot-<%= ::Temple::Utils.escape_html((i)) %>">
|
||||
<td class="is-present-checkbox available-status-code-{{this.benchcoach.availability.statusCode}}">
|
||||
<span>■</span>
|
||||
</td>
|
||||
<td class="jersey-number available-status-code-{{this.benchcoach.availability.statusCode}}{{#if (isStarting this)}} starting{{/if}}">
|
||||
{{this.jerseyNumber}}
|
||||
</td>
|
||||
<td class="player-name available-status-code-{{this.benchcoach.availability.statusCode}}{{#if (isStarting this)}} starting{{/if}}">
|
||||
{{this.lastName}}
|
||||
</td>
|
||||
<td class="player-stats border-left border-right">
|
||||
<span class="decimal-point">.</span>
|
||||
<span class="avg">000</span>
|
||||
<span class="delimiter">/</span>
|
||||
<span class="decimal-point">.</span>
|
||||
<span class="obp">000</span>
|
||||
<span class="delimiter">/</span>
|
||||
<span class="decimal-point">.</span>
|
||||
<span class="slg">000</span>
|
||||
<span class="delimiter">:</span>
|
||||
<span class="pa">00</span>
|
||||
</td>
|
||||
<td class="position-capability pitcher">{{positionCapabilityFor this "P"}}</td>
|
||||
<td class="position-capability catcher">{{positionCapabilityFor this "C"}}</td>
|
||||
<td class="position-capability infield">{{positionCapabilityFor this "IF"}}</td>
|
||||
<td class="position-capability outfield">{{positionCapabilityFor this "OF"}}</td>
|
||||
{{#loopEvents ../upcoming_events}}
|
||||
{{#timepointForMember ../this ../../timeline this}}
|
||||
<td class="availability-on-day future available-status-code-{{this.availability.statusCode}}">
|
||||
{{this.value}}
|
||||
</td>
|
||||
{{/timepointForMember}}
|
||||
{{/loopEvents}}
|
||||
{{#loopEvents ../recent_events}}
|
||||
{{#timepointForMember ../this ../../timeline this}}
|
||||
<td class="availability-on-day past available-status-code-{{this.availability.statusCode}}">
|
||||
{{this.value}}
|
||||
</td>
|
||||
{{/timepointForMember}}
|
||||
{{/loopEvents}}
|
||||
</tr>
|
||||
{{/rosterHistory}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
<section class="lineup-card" id="lineup-card-dugout">
|
||||
<header>
|
||||
<div class="float-left event-title">{{event.formattedTitle}}</div>
|
||||
<div class="float-right homeaway">{{event.gameType}}</div>
|
||||
</header>
|
||||
<div class="starting-lineup-table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="4">Starting</th>
|
||||
<th class="substitution">Substitution</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#offenseLineup 11}}
|
||||
<tr class="slot">
|
||||
<th class="sequence{{#if this.member.lastName}} counter{{/if}}"></th>
|
||||
<td class="player-name">{{this.member.lastName}}</td>
|
||||
<td class="jersey-number">{{this.member.jerseyNumber}}</td>
|
||||
<td class="position">{{this.label}}</td>
|
||||
<td class="substitution"></td>
|
||||
</tr>
|
||||
{{/offenseLineup}}
|
||||
{{#defenseLineup}}
|
||||
<tr class="slot">
|
||||
{{#if (isInPositionOnly this.member)}}{{#if (comparePositionWithFlags "P" this.eventLineupEntry)}}
|
||||
<th class="sequence">PO</th>
|
||||
<td class="player-name">{{this.member.lastName}}</td>
|
||||
<td class="jersey-number">{{this.member.jerseyNumber}}</td>
|
||||
<td class="position">{{positionLabelWithoutFlags this.eventLineupEntry.label}}</td>
|
||||
<td class="substitution"></td>
|
||||
{{/if}}{{/if}}
|
||||
</tr>
|
||||
{{/defenseLineup}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
<section class="lineup-card" id="lineup-card-exchange">
|
||||
<header>
|
||||
<div class="float-left event-title">{{event.formattedTitle}}</div>
|
||||
<div class="float-right homeaway">{{event.gameType}}</div>
|
||||
</header>
|
||||
<div class="starting-lineup-table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="4">Starting</th>
|
||||
<th class="substitution">Substitution</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#offenseLineup 11}}
|
||||
<tr class="slot">
|
||||
<th class="sequence {{#if this.member.lastName}}counter{{/if}}"></th>
|
||||
<td class="player-name">{{this.member.lastName}}</td>
|
||||
<td class="jersey-number">{{this.member.jerseyNumber}}</td>
|
||||
<td class="position">{{this.label}}</td>
|
||||
<td class="substitution"></td>
|
||||
</tr>
|
||||
{{/offenseLineup}}
|
||||
{{#defenseLineup}}
|
||||
<tr class="slot">
|
||||
{{#if (isInPositionOnly this.member)}}{{#if (comparePositionWithFlags "P" this.eventLineupEntry)}}
|
||||
<th class="sequence">PO</th>
|
||||
<td class="player-name">{{this.member.lastName}}</td>
|
||||
<td class="jersey-number">{{this.member.jerseyNumber}}</td>
|
||||
<td class="position">{{positionLabelWithoutFlags this.eventLineupEntry.label}}</td>
|
||||
<td class="substitution"></td>
|
||||
{{/if}}{{/if}}
|
||||
</tr>
|
||||
{{/defenseLineup}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="sheet eventsheet" id="page-2">
|
||||
<section id="back-cover" style="border:solid black;">
|
||||
</section>
|
||||
<section id="front-cover">
|
||||
<header>
|
||||
<div class="homeaway">
|
||||
<span>{{firstLetter event.gameType}}</span>
|
||||
</div>
|
||||
<div class="title">
|
||||
<span class="date-time">{{dateFormat event.startDate "ddd, MMM D h:mm A" }}</span>
|
||||
<span class="location">{{event.locationName}}</span>
|
||||
</div>
|
||||
<div class="game-number">
|
||||
<span class="label">Game #</span>
|
||||
<span class="value">XX</span>
|
||||
</div>
|
||||
</header>
|
||||
<div style="display:block;max-height: 1em;background-color: lightgray;border-bottom: solid 2px black;">
|
||||
</div>
|
||||
<div class="head-to-head">
|
||||
<div class="team">
|
||||
<img src="{{team_preferences.links.teamLogo.href}}">
|
||||
<div>
|
||||
<span class="name">{{team.name}}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{# if event.opponentName}}
|
||||
<div>
|
||||
<div style="text-align: center;font-family: 'Pacifico';">
|
||||
<span>vs</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="opponent">
|
||||
<div>
|
||||
<span class="name">{{event.opponentName}}</span>
|
||||
</div>
|
||||
{{!-- <%= ::Temple::Utils.escape_html((image_tag opponent_logos[event.opponent.id].medium_url)) %> --}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</section>
|
||||
<section class="lineup-card" id="lineup-card-dugout-blank">
|
||||
<div class="starting-lineup-table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="4">
|
||||
Starting
|
||||
</th>
|
||||
<th class="substitution">
|
||||
Substitution
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{!-- <% for i in (0...12) do%> --}}
|
||||
{{#repeat 12}}
|
||||
<tr class="slot">
|
||||
<th class="sequence">
|
||||
</th>
|
||||
<td class="player-name">
|
||||
</td>
|
||||
<td class="jersey-number">
|
||||
</td>
|
||||
<td class="position">
|
||||
</td>
|
||||
<td class="substitution">
|
||||
</td>
|
||||
</tr>
|
||||
{{/repeat}}
|
||||
{{!-- <% end %> --}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
<section class="lineup-card" id="lineup-card-exchange-blank">
|
||||
<div class="starting-lineup-table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="4">
|
||||
Starting
|
||||
</th>
|
||||
<th class="substitution">
|
||||
Substitution
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#repeat 12}}
|
||||
<tr class="slot">
|
||||
<th class="sequence">
|
||||
</th>
|
||||
<td class="player-name">
|
||||
</td>
|
||||
<td class="jersey-number">
|
||||
</td>
|
||||
<td class="position">
|
||||
</td>
|
||||
<td class="substitution">
|
||||
</td>
|
||||
</tr>
|
||||
{{/repeat}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
@@ -1,24 +0,0 @@
|
||||
extends base.pug
|
||||
|
||||
block content
|
||||
.row
|
||||
.text-center.my-2
|
||||
.row
|
||||
h1
|
||||
img.mx-auto(src="media/benchcoach.svg" style="width: 2.5em;")
|
||||
.row
|
||||
h1
|
||||
strong
|
||||
| Welcome to
|
||||
span.text-nowrap BenchCoach
|
||||
.text-center.lead.fst-italic.fw-light
|
||||
| An assistant coach for TeamSnap
|
||||
.row
|
||||
.col.text-center
|
||||
if req.user
|
||||
ul.list-group
|
||||
each team in teams
|
||||
a(class='team list-group-item' href=`/${team.id}/home`) #{team.name} [#{team.seasonName}]
|
||||
else
|
||||
a.btn.btn-outline-primary(href="login")
|
||||
| Login
|
||||
34
src/views/layouts/main.hbs
Normal file
34
src/views/layouts/main.hbs
Normal file
@@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<link rel="stylesheet" href="/css/application.css">
|
||||
{{#if style}}<link rel="stylesheet" href="/css/{{style}}">{{/if}}
|
||||
<title>{{#if title}}{{title}}{{else}}BenchCoach{{/if}}</title>
|
||||
<script>
|
||||
async function setSession() {
|
||||
const response = await fetch("/auth/teamsnap/session_storage")
|
||||
const session_storage = await response.json();
|
||||
console.log(session_storage)
|
||||
for (const [key, value] of Object.entries(session_storage)) {
|
||||
window.sessionStorage.setItem(key,value)
|
||||
}
|
||||
}
|
||||
setSession();
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body class="bg-light">
|
||||
<header class="Header">
|
||||
{{> navbar }}
|
||||
{{{_sections.header}}}
|
||||
</header>
|
||||
<div class="u-padSidesMd u-xs-padSidesLg">
|
||||
<div class="u-max1200 u-flexExpandSides u-xs-size5of6 u-sm-size2of3 u-md-sizeFull u-padBottomMd u-xs-padEndsLg u-sm-padEndsXl">
|
||||
{{{ body }}}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -14,10 +14,7 @@ head
|
||||
|
||||
body.bg-light
|
||||
block navbar
|
||||
.benchcoach-nav.u-flex.u-flexJustifyBetween.u-flexAlignItemsCenter
|
||||
.u-flex.u-flexAlignItemsCenter
|
||||
img(src='/media/benchcoach.svg' alt='TeamSnap Logo' width='30' height='30')
|
||||
h3.u-padLeft.u-colorWhite.u-noMarginBottom BenchCoach
|
||||
include navbar.pug
|
||||
|
||||
.u-spaceSm.u-md-spaceLg
|
||||
block content
|
||||
@@ -1,356 +0,0 @@
|
||||
/* Project specific Javascript goes here. */
|
||||
function onPositionSelectChange(elem) {
|
||||
elem.querySelectorAll("option").forEach((option) => {
|
||||
if (option.innerText == elem.value) {
|
||||
option.setAttribute("selected", "selected");
|
||||
} else {
|
||||
option.removeAttribute("selected");
|
||||
}
|
||||
});
|
||||
colorPositions();
|
||||
}
|
||||
|
||||
function colorPositions() {
|
||||
console.log("Coloring Positions");
|
||||
for (bcLineup of document.getElementsByClassName("event-lineup")) {
|
||||
selected_lineup_positions = Array.from(
|
||||
bcLineup.querySelectorAll(
|
||||
".Panel-row .SelectBox.position-selection option[selected='selected']"
|
||||
)
|
||||
).map((el) => el.value);
|
||||
console.log(selected_lineup_positions);
|
||||
for (position_status of bcLineup.querySelectorAll(".position-status")) {
|
||||
for (class_name of ["text-danger", "text-warning", "text-success"]) {
|
||||
if (position_status.classList.contains(class_name)) {
|
||||
position_status.classList.remove(class_name);
|
||||
}
|
||||
}
|
||||
|
||||
occurrences = selected_lineup_positions.filter(
|
||||
(s) => s == position_status.innerText
|
||||
).length;
|
||||
|
||||
if (occurrences == 1) {
|
||||
position_status.classList.add("text-success");
|
||||
} else if (occurrences > 1) {
|
||||
position_status.classList.add("text-warning");
|
||||
} else {
|
||||
position_status.classList.add("text-danger");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function refresh_lineup_order(itemEl) {
|
||||
let bcLineup = itemEl.closest(".benchcoach-lineup");
|
||||
var player_rows = [];
|
||||
for (tbody of bcLineup.querySelectorAll(
|
||||
"[class*='tbody-benchcoach-starting']"
|
||||
)) {
|
||||
for (row of tbody.rows) {
|
||||
player_rows.push(row);
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < player_rows.length; i++) {
|
||||
var player_order = player_rows[i].querySelector('[id^="sequence"]');
|
||||
var form_element_order = player_rows[i].querySelector('[id$="sequence"]');
|
||||
player_order.innerText = parseInt(player_rows[i].dataset.order);
|
||||
player_rows[i].dataset.order = i;
|
||||
form_element_order.value = i;
|
||||
player_order.innerHTML = i + 1;
|
||||
}
|
||||
var player_rows = bcLineup.getElementsByClassName("tbody-benchcoach-bench")[0]
|
||||
.rows;
|
||||
for (let i = 0; i < player_rows.length; i++) {
|
||||
var player_order = player_rows[i].querySelector('[id^="sequence"]');
|
||||
var form_element_order = player_rows[i].querySelector('[id$="sequence"]');
|
||||
player_rows[i].dataset.order = null;
|
||||
form_element_order.value = null;
|
||||
player_order.innerHTML = null;
|
||||
}
|
||||
}
|
||||
|
||||
function sendToClipboard(itemEl) {
|
||||
let bcLineup = itemEl.closest(".benchcoach-lineup");
|
||||
player_rows = bcLineup.querySelectorAll("[data-position=P]");
|
||||
lineup_export = [];
|
||||
if (player_rows.length > 0) {
|
||||
lineup_export.push(player_rows[0].dataset.playerName);
|
||||
lineup_export.push("", "");
|
||||
} else {
|
||||
lineup_export.push("", "", "");
|
||||
}
|
||||
|
||||
lineup_export.push("");
|
||||
for (position of ["C", "1B", "2B", "3B", "SS", "LF", "CF", "RF", "DH"]) {
|
||||
var player_rows = bcLineup.querySelectorAll(
|
||||
`[data-position=${CSS.escape(position)}]`
|
||||
);
|
||||
if (player_rows.length > 0) {
|
||||
lineup_export.push(player_rows[0].dataset.playerName);
|
||||
} else {
|
||||
lineup_export.push("");
|
||||
}
|
||||
}
|
||||
for (position of ["EH"]) {
|
||||
var player_rows = bcLineup.querySelectorAll(
|
||||
`[data-position=${CSS.escape(position)}]`
|
||||
);
|
||||
for (var i = 0; i < 2; i++) {
|
||||
if (i < player_rows.length) {
|
||||
lineup_export.push(player_rows[i].dataset.playerName);
|
||||
} else {
|
||||
lineup_export.push("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (position of ["DR"]) {
|
||||
let player_rows = bcLineup.querySelectorAll(
|
||||
`[data-position=${CSS.escape(position)}]`
|
||||
);
|
||||
if (player_rows.length > 0) {
|
||||
lineup_export.push(player_rows[0].dataset.playerName);
|
||||
} else {
|
||||
lineup_export.push("");
|
||||
}
|
||||
}
|
||||
|
||||
lineup_export.push("");
|
||||
lineup_export.push("", "");
|
||||
lineup_export.push("");
|
||||
|
||||
for (var i = 0; i < 11; i++) {
|
||||
let player_rows = bcLineup
|
||||
.querySelector(".table-benchcoach-startinglineup")
|
||||
.querySelectorAll(`[data-order=${CSS.escape(i)}]`);
|
||||
if (player_rows.length > 0) {
|
||||
lineup_export.push(player_rows[0].dataset.playerName);
|
||||
} else {
|
||||
lineup_export.push("");
|
||||
}
|
||||
}
|
||||
|
||||
console.dir(lineup_export);
|
||||
var textArea = document.createElement("textarea");
|
||||
textArea.value = lineup_export.join("\n");
|
||||
|
||||
// Avoid scrolling to bottom
|
||||
textArea.style.top = "0";
|
||||
textArea.style.left = "0";
|
||||
textArea.style.position = "fixed";
|
||||
|
||||
document.body.appendChild(textArea);
|
||||
textArea.focus();
|
||||
textArea.select();
|
||||
|
||||
try {
|
||||
var successful = document.execCommand("copy");
|
||||
var msg = successful ? "successful" : "unsuccessful";
|
||||
console.log("Copying text command was " + msg);
|
||||
} catch (err) {
|
||||
console.error("Oops, unable to copy", err);
|
||||
}
|
||||
|
||||
document.body.removeChild(textArea);
|
||||
}
|
||||
|
||||
for (bcLineup of document.querySelectorAll(".Panel:has(.lineup-slot)")) {
|
||||
var startinglineup = new Sortable.create(
|
||||
bcLineup.querySelector(".slot-set"),
|
||||
{
|
||||
animation: 150,
|
||||
handle: ".drag-handle",
|
||||
ghostClass: "ghost",
|
||||
group: {
|
||||
name: bcLineup.id,
|
||||
put: [bcLineup.id],
|
||||
pull: [bcLineup.id],
|
||||
},
|
||||
onAdd: function (/**Event*/ evt) {
|
||||
// Add to Lineup
|
||||
var itemEl = evt.item; // dragged HTMLElement
|
||||
var player_order = itemEl.querySelector('[id^="sequence-member"]');
|
||||
var player_available = itemEl.querySelector(
|
||||
'[class^="member-availability-status"]'
|
||||
);
|
||||
refresh_lineup_order(itemEl);
|
||||
if (player_order.classList.contains("d-none")) {
|
||||
player_order.classList.remove("d-none");
|
||||
}
|
||||
// player_available.classList.add('d-none')
|
||||
},
|
||||
onUpdate: function (/**Event*/ evt) {
|
||||
console.log("update to lineup");
|
||||
var itemEl = evt.item; // dragged HTMLElement
|
||||
refresh_lineup_order(itemEl);
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function copyEmailTable(itemEl, subject, recipients) {
|
||||
// Create container for the HTML
|
||||
// [1]
|
||||
let bcLineup = itemEl.closest(".benchcoach-lineup");
|
||||
var container = document.createElement("div");
|
||||
var tbl = document.createElement("table");
|
||||
|
||||
let thead = tbl.createTHead();
|
||||
let thead_row = thead.insertRow();
|
||||
let thead_row_cell = thead_row.insertCell();
|
||||
thead_row_cell.appendChild(
|
||||
document
|
||||
.createElement("h3")
|
||||
.appendChild(document.createTextNode("STARTING LINEUP"))
|
||||
);
|
||||
thead_row_cell.colSpan = 3;
|
||||
thead_row_cell.classList.add("title-cell");
|
||||
var tbody = tbl.createTBody();
|
||||
for (row of bcLineup.querySelector(".table-benchcoach-startinglineup").rows) {
|
||||
let tr = tbody.insertRow();
|
||||
cell = tr.insertCell();
|
||||
cell.classList.add("sequence-cell");
|
||||
cell.appendChild(document.createTextNode(parseInt(row.dataset.order) + 1));
|
||||
cell = tr.insertCell();
|
||||
cell.appendChild(document.createTextNode(row.dataset.playerName));
|
||||
cell.classList.add("name-cell");
|
||||
tr.insertCell().appendChild(document.createTextNode(row.dataset.position));
|
||||
}
|
||||
|
||||
if (
|
||||
bcLineup.querySelector(".table-benchcoach-startingpositionalonly").rows
|
||||
.length > 0
|
||||
) {
|
||||
var tr = tbody.insertRow();
|
||||
cell = tr.insertCell();
|
||||
cell.colSpan = 3;
|
||||
cell.appendChild(document.createTextNode("STARTING (POS. ONLY)"));
|
||||
cell.classList.add("title-cell");
|
||||
|
||||
for (row of bcLineup.querySelector(
|
||||
".table-benchcoach-startingpositionalonly"
|
||||
).rows) {
|
||||
var tr = tbody.insertRow();
|
||||
cell = tr.insertCell();
|
||||
cell.classList.add("sequence-cell");
|
||||
cell.appendChild(document.createTextNode(""));
|
||||
cell = tr.insertCell();
|
||||
cell.appendChild(document.createTextNode(row.dataset.playerName));
|
||||
cell.classList.add("name-cell");
|
||||
tr.insertCell().appendChild(
|
||||
document.createTextNode(row.dataset.position)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (bcLineup.querySelector(".table-benchcoach-bench").rows.length > 0) {
|
||||
var tr = tbody.insertRow();
|
||||
cell = tr.insertCell();
|
||||
cell.colSpan = 3;
|
||||
cell.appendChild(document.createTextNode("SUBS"));
|
||||
cell.classList.add("title-cell");
|
||||
|
||||
for (row of bcLineup.querySelector(".table-benchcoach-bench").rows) {
|
||||
var tr = tbody.insertRow();
|
||||
cell = tr.insertCell();
|
||||
cell.classList.add("sequence-cell");
|
||||
availability_status = {
|
||||
None: "UNK",
|
||||
0: "NO",
|
||||
2: "MAY",
|
||||
1: "YES",
|
||||
}[row.dataset.availabilityStatuscode];
|
||||
cell.appendChild(document.createTextNode(availability_status));
|
||||
cell = tr.insertCell();
|
||||
cell.appendChild(document.createTextNode(row.dataset.playerName));
|
||||
cell.classList.add("name-cell");
|
||||
tr.insertCell().appendChild(document.createTextNode(""));
|
||||
}
|
||||
}
|
||||
|
||||
if (bcLineup.querySelector(".table-benchcoach-out").rows.length > 0) {
|
||||
var tr = tbody.insertRow();
|
||||
cell = tr.insertCell();
|
||||
cell.colSpan = 3;
|
||||
cell.appendChild(document.createTextNode("OUT"));
|
||||
cell.classList.add("title-cell");
|
||||
|
||||
for (row of bcLineup.querySelector(".table-benchcoach-out").rows) {
|
||||
var tr = tbody.insertRow();
|
||||
cell = tr.insertCell();
|
||||
cell.classList.add("sequence-cell");
|
||||
availability_status = {
|
||||
None: "UNK",
|
||||
0: "NO",
|
||||
1: "MAY",
|
||||
2: "YES",
|
||||
}[row.dataset.availabilityStatuscode];
|
||||
cell.appendChild(document.createTextNode(availability_status));
|
||||
tr.insertCell().appendChild(
|
||||
document.createTextNode(row.dataset.playerName)
|
||||
);
|
||||
tr.insertCell().appendChild(document.createTextNode(""));
|
||||
}
|
||||
}
|
||||
|
||||
container.appendChild(tbl);
|
||||
for (cell of container.getElementsByClassName("title-cell")) {
|
||||
cell.setAttribute(
|
||||
"style",
|
||||
"font-weight:bold;background-color:#323669;color:#fff;padding:2px 5px;"
|
||||
);
|
||||
}
|
||||
|
||||
for (cell of container.getElementsByClassName("sequence-cell")) {
|
||||
cell.setAttribute("style", "font-weight:bold;padding:2px 5px;");
|
||||
}
|
||||
|
||||
for (cell of container.getElementsByClassName("name-cell")) {
|
||||
cell.setAttribute("style", "width:200px;");
|
||||
}
|
||||
|
||||
// Detect all style sheets of the page
|
||||
var activeSheets = Array.prototype.slice
|
||||
.call(document.styleSheets)
|
||||
.filter(function (sheet) {
|
||||
return !sheet.disabled;
|
||||
});
|
||||
|
||||
// Mount the container to the DOM to make `contentWindow` available
|
||||
// [3]
|
||||
document.body.appendChild(container);
|
||||
|
||||
// Copy to clipboard
|
||||
// [4]
|
||||
window.getSelection().removeAllRanges();
|
||||
|
||||
var range = document.createRange();
|
||||
range.selectNode(container);
|
||||
window.getSelection().addRange(range);
|
||||
|
||||
// [5.1]
|
||||
document.execCommand("copy");
|
||||
|
||||
// [5.2]
|
||||
for (var i = 0; i < activeSheets.length; i++) activeSheets[i].disabled = true;
|
||||
|
||||
// [5.3]
|
||||
// document.execCommand('copy')
|
||||
|
||||
// [5.4]
|
||||
for (var i = 0; i < activeSheets.length; i++)
|
||||
activeSheets[i].disabled = false;
|
||||
|
||||
// Remove the container
|
||||
// [6]
|
||||
document.body.removeChild(container);
|
||||
subject_encoded = encodeURIComponent(subject);
|
||||
window.open(
|
||||
"readdle-spark://compose?recipient=manager@chihounds.com&subject=" +
|
||||
subject +
|
||||
"&bcc=" +
|
||||
recipients
|
||||
);
|
||||
}
|
||||
27
src/views/login.hbs
Normal file
27
src/views/login.hbs
Normal file
@@ -0,0 +1,27 @@
|
||||
<div class="Grid Grid--fit Grid--withGutter u-max1200 u-flexExpandSides u-xs-size5of6 u-sm-size2of3 u-md-sizeFull u-padBottomMd u-xs-padEndsLg u-sm-padEndsXl">
|
||||
<div class="Grid-cell u-size5of12">
|
||||
<div class="Panel u-padLg u-spaceSidesAuto">
|
||||
<h1 class="u-spaceSidesAuto u-spaceBottomLg">Sign in</h1>
|
||||
<div>
|
||||
<a class="Button Button--large Button--orange u-spaceSidesAuto" href="/login/federated/teamsnap">
|
||||
{{{embeddedSvgFromPath "/media/teamsnap_star.svg"}}}
|
||||
<span>TeamSnap</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="Grid-cell u-size7of12 u-textCenter">
|
||||
<h1>
|
||||
<img src="/media/benchcoach.svg" style="width: 2.5em;">
|
||||
</h1>
|
||||
<h1>
|
||||
<strong>
|
||||
Welcome to
|
||||
<span class="text-nowrap">BenchCoach</span>
|
||||
</strong>
|
||||
</h1>
|
||||
<div class="lead fst-italic fw-light">
|
||||
An assistant coach for TeamSnap
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,19 +0,0 @@
|
||||
extends base.pug
|
||||
|
||||
block content
|
||||
.Grid.Grid--fit.Grid--withGutter.u-max1200.u-flexExpandSides.u-xs-size5of6.u-sm-size2of3.u-md-sizeFull.u-padBottomMd.u-xs-padEndsLg.u-sm-padEndsXl
|
||||
.Grid-cell.u-size5of12
|
||||
.Panel.u-padLg.u-spaceSidesAuto
|
||||
h1.u-spaceSidesAuto.u-spaceBottomLg Sign in
|
||||
a(class="Button Button--large Button--orange" href="/login/federated/teamsnap").u-spaceSidesAuto
|
||||
img(src="/media/teamsnap_star.svg").icon.u-spaceRightSm
|
||||
span TeamSnap
|
||||
.Grid-cell.u-size7of12.u-textCenter
|
||||
h1
|
||||
img(src="media/benchcoach.svg" style="width: 2.5em;")
|
||||
h1
|
||||
strong
|
||||
| Welcome to
|
||||
span.text-nowrap BenchCoach
|
||||
.lead.fst-italic.fw-light
|
||||
| An assistant coach for TeamSnap
|
||||
@@ -1,14 +0,0 @@
|
||||
extends base.pug
|
||||
|
||||
block content
|
||||
.Panel
|
||||
.Panel-header
|
||||
.Panel-title Roster
|
||||
.Panel-body
|
||||
each member in members
|
||||
a(class="" href=`/${team_id}/member/${member.id}`).Panel-row--withCells
|
||||
.Panel-cell
|
||||
|#{member.firstName}
|
||||
.Panel-cell
|
||||
|#{member.lastName}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
mixin availability-progress-bar(availabilitySummary, team)
|
||||
.progress
|
||||
div(class="progress-bar bg-success fw-bold" role="progressbar" style=`
|
||||
width: ${((availabilitySummary.playerGoingCount/team.playerMemberCount)*100).toString() + "%"}`)
|
||||
|#{availabilitySummary.playerGoingCount}
|
||||
div(class="progress-bar bg-info fw-bold" role="progressbar" style=`
|
||||
width: ${((availabilitySummary.playerMaybeCount/team.playerMemberCount)*100).toString() + "%"}`)
|
||||
|#{availabilitySummary.playerMaybeCount}
|
||||
div(class="progress-bar bg-danger fw-bold" role="progressbar" style=`
|
||||
width: ${((availabilitySummary.playerNotGoingCount/team.playerMemberCount)*100).toString() + "%"}`)
|
||||
|#{availabilitySummary.playerNotGoingCount}
|
||||
div(class="progress-bar text-secondary fw-bold" role="progressbar" style=`
|
||||
width: ${((availabilitySummary.playerUnknownCount/team.playerMemberCount)*100).toString() + "%"};
|
||||
background-color: var(--bs-gray-200)`)
|
||||
|#{availabilitySummary.playerUnknownCount}
|
||||
@@ -1,22 +0,0 @@
|
||||
mixin lineup-slot(item, index)
|
||||
-
|
||||
if (item.type == "eventLineupEntry") {
|
||||
var availability_status_code = item.availabilityStatusCode
|
||||
} else if (item.type == "availability") {
|
||||
var availability_status_code = item.statusCode
|
||||
}
|
||||
.Panel-row.Panel-row--withCells.lineup-slot
|
||||
.Panel-cell.Panel-cell--header.u-padXs.u-size1of12
|
||||
.u-flexAlignSelfCenter
|
||||
|#{index+1}
|
||||
div(class=`Panel-cell availability-status-code-${availability_status_code}`).u-padXs.u-size8of12
|
||||
span.lastname #{item.member.lastName}
|
||||
span.jerseynumber ##{item.member.jerseyNumber}
|
||||
.Panel-cell.u-padXs.u-size2of12
|
||||
.SelectBox.position-selection
|
||||
select(onchange="onPositionSelectChange(this)").position-select-box.SelectBox-options
|
||||
each pos in ["P", "C", "1B", "2B", "3B", "SS", "LF", "CF", "RF", "EH", "DH"]
|
||||
option(selected=item.label==pos) #{pos}
|
||||
.Panel-cell.u-padXs.u-flexAlignSelfCenter.u-size1of12
|
||||
.drag-handle
|
||||
i.bi.bi-grip-vertical.text-secondary.drag-handle
|
||||
@@ -1,39 +0,0 @@
|
||||
extends base
|
||||
block content
|
||||
.Panel
|
||||
.Panel-header
|
||||
.Panel-title #{opponent.name}
|
||||
.Panel-body
|
||||
.Panel-row.Panel-row--withCells
|
||||
.Panel-cell.Panel-cell--header ID
|
||||
.panel-cell #{opponent.id}
|
||||
Button(onclick=`navigator.clipboard.writeText("${opponent.id}");`).Button
|
||||
i.bi.bi-clipboard.Icon
|
||||
.Panel-row.Panel-row--withCells
|
||||
.Panel-cell.Panel-cell--header Contact Name
|
||||
.panel-cell #{opponent.contactsName}
|
||||
.Panel-row.Panel-row--withCells
|
||||
.Panel-cell.Panel-cell--header Contact Phone
|
||||
.panel-cell #{opponent.contactsPhone}
|
||||
.Panel-row.Panel-row--withCells
|
||||
.Panel-cell.Panel-cell--header Contact Email
|
||||
.panel-cell #{opponent.contactsEmail}
|
||||
.Panel-row.Panel-row--withCells
|
||||
.Panel-cell.Panel-cell--header Logo
|
||||
.panel-cell
|
||||
if opponent_logo
|
||||
img(src=`${opponent_logo.mediumUrl}` width="64" height="64")
|
||||
a.Button(target="_blank" rel="noopener noreferrer" href=`https://go.teamsnap.com/${team_id}/files/view/${opponent_logo.id}`).Button
|
||||
i.bi.bi-asterisk.Icon
|
||||
else
|
||||
if team_media_group
|
||||
a.Button(target="_blank" rel="noopener noreferrer" href=`https://go.teamsnap.com/${team_id}/files/list/${team_media_group.id}`) Upload
|
||||
else
|
||||
a.Button(target="_blank" rel="noopener noreferrer" href=`https://go.teamsnap.com/${team_id}/files/`) Upload
|
||||
Button(onclick=`navigator.clipboard.writeText("opponent-logo-${opponent.id}.png");`).Button
|
||||
i.bi.bi-clipboard.Icon
|
||||
span Copy Filename
|
||||
.Panel-row.Panel-row--withCells
|
||||
.Panel-cell.Panel-cell--header Notes
|
||||
.panel-cell #{opponent.Notes}
|
||||
|
||||
14
src/views/opponent/list.hbs
Normal file
14
src/views/opponent/list.hbs
Normal file
@@ -0,0 +1,14 @@
|
||||
<h1>
|
||||
{{title}}
|
||||
</h1>
|
||||
<div class="Panel">
|
||||
<div class="Panel-body">
|
||||
{{#each opponents}}
|
||||
<div class="Panel-row Panel-row--withCells u-textDecorationNone">
|
||||
<a class="Panel-cell" href="opponent/{{this.id}}">
|
||||
{{this.name}}
|
||||
</a>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
79
src/views/opponent/show.hbs
Normal file
79
src/views/opponent/show.hbs
Normal file
@@ -0,0 +1,79 @@
|
||||
<div class="Panel">
|
||||
<div class="Panel-header">
|
||||
<div class="Panel-title">
|
||||
{{opponent.name}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="Panel-body">
|
||||
<div class="Panel-row Panel-row--withCells">
|
||||
<div class="Panel-cell Panel-cell--header">
|
||||
ID
|
||||
</div>
|
||||
<div class="Panel-cell">
|
||||
{{opponent.id}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="Panel-row Panel-row--withCells">
|
||||
<div class="Panel-cell Panel-cell--header">
|
||||
Contact Name
|
||||
</div>
|
||||
<div class="Panel-cell">
|
||||
{{opponent.contactsName}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="Panel-row Panel-row--withCells">
|
||||
<div class="Panel-cell Panel-cell--header">
|
||||
Contact Phone
|
||||
</div>
|
||||
<div class="Panel-cell">
|
||||
{{opponent.contactsPhone}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="Panel-row Panel-row--withCells">
|
||||
<div class="Panel-cell Panel-cell--header">
|
||||
Contact Email
|
||||
</div>
|
||||
<div class="Panel-cell">
|
||||
{{opponent.contactsEmail}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="Panel-row Panel-row--withCells">
|
||||
<div class="Panel-cell Panel-cell--header">
|
||||
Logo
|
||||
</div>
|
||||
<div class="Panel-cell">
|
||||
{{#if opponent_logo}}
|
||||
<img src="{{opponent_logo.mediumUrl}}" width="64" height="64" />
|
||||
{{else}}
|
||||
<form name="upload-opponent-logo" action="{{opponent.id}}/upload_logo" method="post" enctype="multipart/form-data" hidden>
|
||||
{{!-- THIS DOESN'T WORK XHR2 ERRORS (FORMDATA) --}}
|
||||
<input type="hidden" name="_csrf" value="{{csrfToken}}">
|
||||
<input type="hidden" name="csrfToken" value="{{csrfToken}}">
|
||||
<input type="hidden" name="teamMediaGroupId" value="{{team_media_group.id}}">
|
||||
<input type="hidden" name="memberId" value="{{member.id}}">
|
||||
<input type="hidden" name="teamId" value="{{team.id}}">
|
||||
<input type="hidden" name="description" value="team-logo-{{opponent.id}}.png">
|
||||
<div class="FieldGroup">
|
||||
<label for='file' class="FieldGroup-label">Select files</label>
|
||||
<input id='file' name='file' type="file">
|
||||
<button class="submit-btn Button" type="submit">Upload</button>
|
||||
</div>
|
||||
</form>
|
||||
<div
|
||||
class="Button"
|
||||
onclick="navigator.clipboard.writeText('opponent-logo-{{
|
||||
opponent.id
|
||||
}}.png');window.open('https://go.teamsnap.com/{{team.id}}/files/list/{{team_media_group.id}}');"
|
||||
>
|
||||
<img class="Icon" src="/bootstrap-icons/clipboard.svg" />
|
||||
<span>
|
||||
Copy Filename and Go to Teamsnap
|
||||
</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/js/teamsnap.min.js"></script>
|
||||
<script src="/js/opponent.js"></script>
|
||||
@@ -1,10 +0,0 @@
|
||||
extends base
|
||||
|
||||
block content
|
||||
.Panel
|
||||
.Panel-header
|
||||
.Panel-title Opponents
|
||||
.Panel-body
|
||||
each opponent in opponents
|
||||
.Panel-row
|
||||
a(class='opponent' href=`/${team.id}/opponent/${opponent.id}`) #{opponent.name}
|
||||
30
src/views/partials/navbar.hbs
Normal file
30
src/views/partials/navbar.hbs
Normal file
@@ -0,0 +1,30 @@
|
||||
<div class="Header-container Grid u-flexAlignItemsCenter">
|
||||
<div class="Grid-cell u-sizeFill">
|
||||
<div class="Header-banner Grid u-flexAlignItemsCenter">
|
||||
<a href="/" class="Grid-cell u-sizeFit u-flexInline u-flexAlignItemsCenter u-textDecorationNone">
|
||||
<div class="Header-bannerLogo">
|
||||
<img class="logo" src="/media/benchcoach.svg" alt="BenchCoach Logo">
|
||||
</div>
|
||||
</a>
|
||||
<div class="Grid-cell u-flexInline u-flexJustifyEnd u-sizeFill u-padSidesSm">
|
||||
{{#if user}}
|
||||
<div class="Popup">
|
||||
<div class="Button Button--small Popup-toggle" onclick="this.closest('.Popup').querySelector('.Popup-container').classList.toggle('is-open')">
|
||||
Account
|
||||
</div>
|
||||
<div class="Popup-container Popup-container--down Popup-container--right u-sizeFit">
|
||||
<div class="Popup-content u-padXs u-sizeFit u-fontSizeSm">
|
||||
<h6 class="h6 title u-textNoWrap u-fontSizeSm u-textSemiBold">{{user.first_name}} {{user.last_name}}</h6>
|
||||
<div class="u-textNoWrap u-fontSizeSm">{{user.email}}</div>
|
||||
<hr class="Divider u-spaceEndsNone">
|
||||
<a href="/logout">Logout</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
25
src/views/partials/navbar.pug
Normal file
25
src/views/partials/navbar.pug
Normal file
@@ -0,0 +1,25 @@
|
||||
header.Header
|
||||
.Header-container.Grid.u-flexAlignItemsCenter
|
||||
.Grid-cell.u-sizeFill
|
||||
.Header-banner.Grid.u-flexAlignItemsCenter
|
||||
a.Grid-cell.u-sizeFit.u-flexInline.u-flexAlignItemsCenter.u-textDecorationNone href=url_for(root_path)
|
||||
div.Header-bannerLogo
|
||||
img(class='logo' src='/media/benchcoach.svg' alt='BenchCoach Logo')
|
||||
span
|
||||
- if defined?(team)
|
||||
h1.Header-bannerTitle #{team.name}
|
||||
- else
|
||||
h1.Header-bannerTitle BenchCoach
|
||||
.Grid-cell.u-flexInline.u-flexJustifyEnd.u-sizeFill.u-padSidesSm
|
||||
- if @user
|
||||
.Popup
|
||||
.Button.Button--small.Popup-toggle onclick="this.closest('.Popup').querySelector('.Popup-container').classList.toggle('is-open')"
|
||||
| Account
|
||||
.Popup-container.Popup-container--down.Popup-container--right.u-sizeFit
|
||||
.Popup-content.u-padXs.u-sizeFit.u-fontSizeSm
|
||||
h6.title.u-textNoWrap.u-fontSizeSm.u-textSemiBold="#{@user['first_name']} #{@user['last_name']}"
|
||||
.u-textNoWrap.u-fontSizeSm="#{@user['email']}"
|
||||
hr.Divider.u-spaceEndsNone
|
||||
a href=url_for(logout_path) Logout
|
||||
|
||||
.Grid-cell.u-sizeFit
|
||||
@@ -1,24 +0,0 @@
|
||||
extends base.pug
|
||||
|
||||
block content
|
||||
.Panel
|
||||
.Panel-body
|
||||
.Panel-row
|
||||
h2.Panel-title #{team.name}
|
||||
p #{team.seasonName}
|
||||
.Panel
|
||||
.Panel-body
|
||||
.Panel-row
|
||||
a(href=`/${team.id}/events`).u-fontSizeXl-
|
||||
<svg viewBox="0 0 960 960" role="presentation" class="Icon">
|
||||
<path d="M890 131c11.3 2.7 20.5 8.3 27.5 17s10.5 18.7 10.5 30v699c0 11.3-3.5 21.3-10.5 30s-16.2 14.3-27.5 17l-8 2c-4.7.7-11 1.7-19 3s-17.7 3-29 5-24.3 3.8-39 5.5-30.5 3.5-47.5 5.5-35.7 4-56 6-41.3 3.7-63 5-45.3 2.3-71 3-51.5 1-77.5 1-51.8-.3-77.5-1-49.3-1.7-71-3-42.7-3-63-5-39-4-56-6-32.8-3.8-47.5-5.5-27.7-3.5-39-5.5-21-3.7-29-5-14.3-2.3-19-3l-8-2c-11.3-2.7-20.5-8.3-27.5-17S32 888.3 32 877V178c0-11.3 3.5-21.3 10.5-30s16.2-14.3 27.5-17c.7 0 4.5-.7 11.5-2s17.8-3.2 32.5-5.5 30-4.5 46-6.5v43c0 23.3 8.3 42.5 25 57.5s36.7 22.5 60 22.5c-14-12.7-21-28.7-21-48V64c0-17.3 6.3-32.3 19-45s27.7-19 45-19 32.3 6.3 45 19 19 27.7 19 45v35c40-2 82.7-3 128-3 28.7 0 50 .3 64 1v63c0 23.3 8.3 42.5 25 57.5s36.7 22.5 60 22.5c-14-12.7-21-28.7-21-48V64c0-17.3 6.3-32.3 19-45s27.7-19 45-19 32.3 6.3 45 19 19 27.7 19 45v45c64 6.7 115.3 14 154 22zM480 869c122.7 0 240-9.3 352-28V384H128v457c112 18.7 229.3 28 352 28zm256-421v128H608V448h128zm-192 0v128H416V448h128zm0 320H416V640h128v128zm-192 0H224V640h128v128zm384 0H608V640h128v128z"></path>
|
||||
</svg>
|
||||
| Events
|
||||
.Panel-row
|
||||
a(href=`/${team.id}/members`)
|
||||
<svg viewBox="0 0 960 960" class="Icon"><path d="M959 714c2 8 .7 16-4 24-5.3 7.3-12.3 11.7-21 13-9.3 4.7-66.7 8.3-172 11-28.7-60.7-73.3-109.7-134-147-17.3-10-39-19.7-65-29-6.7-3.3-12-5.7-16-7 31.3-49.3 52.3-97 63-143s13.5-84.3 8.5-115-15.2-58.3-30.5-83c-28-47.3-63.3-80.7-106-100 18.7-24 37.2-41.7 55.5-53S579 68 607 68c33.3 0 63.7 7.7 91 23s49.3 36.7 66 64c43.3 71.3 32.3 157.7-33 259-20 28.7-27.7 50.7-23 66 2 7.3 8 14.5 18 21.5s18.7 12.2 26 15.5 19.3 8.3 36 15c26 10.7 43.7 18.7 53 24 64.7 39.3 104 92 118 158zM352 892c-70 0-132-1-186-3s-90.2-4-108.5-6-28.8-3.3-31.5-4c-8.7-.7-15.7-5-21-13-4.7-6.7-6-14.7-4-24 14-66 53-118.7 117-158 8-4.7 25.7-12.7 53-24 16.7-6.7 28.7-11.7 36-15s16-8.5 26-15.5 16-14.2 18-21.5c4.7-14.7-2.7-36.7-22-66-65.3-102-76.7-188.3-34-259 16.7-27.3 38.8-48.7 66.5-64s57.8-23 90.5-23c33.3 0 63.8 7.7 91.5 23s49.8 36.7 66.5 64c42.7 70.7 31.3 157-34 259-19.3 29.3-26.7 51.3-22 66 2 7.3 8 14.5 18 21.5s18.7 12.2 26 15.5 19.3 8.3 36 15c27.3 11.3 45 19.3 53 24 63.3 39.3 102.7 92 118 158 2 8.7.3 16.7-5 24-5.3 8-12.3 12.3-21 13-2.7.7-13.3 2-32 4s-55 4-109 6-116 3-186 3z"></path></svg>
|
||||
| Roster
|
||||
.Panel-row
|
||||
a(href=`/${team.id}/opponents`)
|
||||
<svg viewBox="0 0 960 960" class="Icon"><path d="M959 628c2 6.7.7 13.7-4 21s-10.7 11.3-18 12l-7 1c-4.7.7-11.8 1.5-21.5 2.5s-21.5 2-35.5 3-33.2 1.8-57.5 2.5-50.8 1.3-79.5 2c-6-4.7-12.7-9.2-20-13.5s-15.2-9-23.5-14S678 635.7 674 633c-10.7-5.3-21-11.3-31-18 70-92.7 84-184.7 42-276-16.7-36-40-64-70-84s-62.7-32.3-98-37c0-23.3 5.3-47.3 16-72 12.7-28 32-48.7 58-62s53-20 81-20 55 6.7 81 20 45.3 34 58 62c32 70 16.3 141.7-47 215-19.3 22.7-18 46.3 4 71 6.7 8 26.2 21.3 58.5 40s55.2 32.7 68.5 42c7.3 5.3 13.8 10.2 19.5 14.5s10.5 9.3 14.5 15 7.2 10 9.5 13 4.7 8.2 7 15.5 3.8 12.3 4.5 15 2.2 9.2 4.5 19.5 3.8 17.5 4.5 21.5zm-673 5c-4 2.7-10.2 6.5-18.5 11.5s-16.2 9.7-23.5 14-14 8.8-20 13.5c-20.7 0-40.3-.3-59-1s-34.7-1.3-48-2-25.3-1.3-36-2-19.5-1.3-26.5-2-12.8-1.3-17.5-2-8.3-1-11-1l-3-1c-7.3-.7-13.3-4.7-18-12-4.7-6-6-13-4-21 1.3-4.7 3-11.8 5-21.5s3.3-16.2 4-19.5 2.2-8.5 4.5-15.5 4.7-12 7-15S27 549.3 31 544s8.7-10.3 14-15 12-9.7 20-15c14-10 37-24.3 69-43s51.3-31.7 58-39c22-24.7 23.3-48.3 4-71-63.3-73.3-79-145-47-215 12.7-28 32-48.7 58-62s53-20 81-20 55 6.7 81 20 45.3 34 58 62c10.7 24.7 16 48.7 16 72-80 11.3-136.3 51.7-169 121-41.3 91.3-27 183.3 43 276-2.7 2-5.7 4-9 6s-7.2 4.2-11.5 6.5-7.5 4.2-9.5 5.5h-1zm194 263c-28 0-54.5-.2-79.5-.5s-46.2-.8-63.5-1.5-33-1.5-47-2.5-25.5-1.8-34.5-2.5-16.5-1.3-22.5-2-10.3-1-13-1l-5-1c-7.3-.7-13.3-4.7-18-12-4.7-6-6-13-4-21 1.3-4.7 3-11.8 5-21.5s3.3-16.2 4-19.5 2.2-8.5 4.5-15.5 4.7-12 7-15 5.5-7.2 9.5-12.5 8.7-10.3 14-15 12-9.7 20-15c14-10 37-24.3 69-43s51.3-31.7 58-39c22-24.7 23.3-48.3 4-71-63.3-73.3-79-145-47-215 12.7-28 32-48.7 58-62s53-20 81-20 55 6.7 81 20 45.3 34 58 62c32 70 16.3 141.7-47 215-19.3 22.7-18 46.3 4 71 6.7 8 26.2 21.3 58.5 40s55.2 32.7 68.5 42c16.7 12 29 23.2 37 33.5s13.5 21.7 16.5 34S763 833.3 767 852c2 7.3.7 14.3-4 21-4.7 7.3-10.7 11.3-18 12l-5 1c-2.7 0-7 .3-13 1s-13.5 1.3-22.5 2-20.7 1.5-35 2.5-30.2 1.8-47.5 2.5-38.3 1.2-63 1.5-51 .5-79 .5z"></path></svg>
|
||||
| Opponents
|
||||
52
src/views/team/home.hbs
Normal file
52
src/views/team/home.hbs
Normal file
@@ -0,0 +1,52 @@
|
||||
<div class=" Grid u-spaceBottomSm">
|
||||
<div class=" Grid-cell u-spaceNone u-sizeFit">
|
||||
<img src="{{team_preferences.links.teamLogo.href}}", style="height: 64px;">
|
||||
</div>
|
||||
<div class=" Grid-cell u-sizeFill u-spaceNone">
|
||||
<h2 class=" u-spaceNone">{{team.name}}</h2>
|
||||
<p class=" u-spaceNone">{{team.season_name}}</p>
|
||||
<small class=" u-spaceNone"><a href="{{team.leagueUrl}}">{{team.leagueName}}</a></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class=" Grid-cell u-sizeFit">
|
||||
<div class=" u-flex u-flexAlignItemsCenter u-flexJustifyEnd">
|
||||
<div class="ButtonGroup">
|
||||
<a class="Button" href="schedule">
|
||||
<img src ="/teamsnap-ui/assets/icons/schedule.svg" class="Icon">
|
||||
<span class="span u-hidden u-xs-inline">Schedule</span>
|
||||
</a>
|
||||
<a class="Button" href="members">
|
||||
<img src ="/teamsnap-ui/assets/icons/roster.svg" class="Icon">
|
||||
<span class="span u-hidden u-xs-inline">Roster</span>
|
||||
</a>
|
||||
<a class="Button" href="opponents">
|
||||
<img src ="/teamsnap-ui/assets/icons/team.svg" class="Icon">
|
||||
<span class="span u-hidden u-xs-inline">Opponents</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" Panel Panel--full">
|
||||
<div class=" Panel-header">
|
||||
<h2 class=" Panel-title">Upcoming Events</h2>
|
||||
</div>
|
||||
<div class=" Panel-body">
|
||||
{{#each upcoming_events}}
|
||||
{{>event_panel event=this}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" Panel Panel--full">
|
||||
<div class=" Panel-header">
|
||||
<h2 class=" Panel-title">Recent Events</h2>
|
||||
</div>
|
||||
<div class=" Panel-body">
|
||||
{{#each recent_events}}
|
||||
{{>event_panel event=this}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
49
src/views/team/list.hbs
Normal file
49
src/views/team/list.hbs
Normal file
@@ -0,0 +1,49 @@
|
||||
<div class=" Panel u-sm-size1of2 u-spaceSidesAuto u-spaceSm u-maxWidthSm">
|
||||
<div class="Panel-header">
|
||||
<h3 class="Panel-title">
|
||||
My Teams
|
||||
</h3>
|
||||
</div>
|
||||
<div class="Panel-body">
|
||||
{{#each teams}}
|
||||
{{#unless this.isArchivedSeason}}
|
||||
<a
|
||||
class="Panel-row Panel-row--withCells u-textDecorationNone"
|
||||
href="/{{this.id}}/home"
|
||||
>
|
||||
<div class=" Panel-cell u-flexGrow1 u-textNoWrap">
|
||||
<b>
|
||||
{{this.name}}
|
||||
</b>
|
||||
</div>
|
||||
<div class=" Panel-cell u-fontSizeSm u-size1of3 u-textRight">
|
||||
{{this.seasonName}}
|
||||
</div>
|
||||
</a>
|
||||
{{/unless}}
|
||||
{{/each}}
|
||||
<div class="Panel-header">
|
||||
<h3 class="Panel-title">
|
||||
Archived Seasons
|
||||
</h3>
|
||||
</div>
|
||||
{{#each teams}}
|
||||
{{#if this.isArchivedSeason}}
|
||||
<a
|
||||
class="Panel-row Panel-row--withCells u-textDecorationNone"
|
||||
href="/{{this.id}}/home"
|
||||
>
|
||||
<div class=" Panel-cell u-flexGrow1 u-textNoWrap">
|
||||
<b>
|
||||
{{this.name}}
|
||||
</b>
|
||||
</div>
|
||||
<div class=" Panel-cell u-fontSizeSm u-size1of3 u-textRight">
|
||||
{{this.seasonName}}
|
||||
</div>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,20 +0,0 @@
|
||||
extends base.pug
|
||||
|
||||
block content
|
||||
.row
|
||||
.text-center.my-2
|
||||
.row
|
||||
h1
|
||||
img.mx-auto(src="media/benchcoach.svg" style="width: 2.5em;")
|
||||
.row
|
||||
h1
|
||||
strong
|
||||
| Welcome to
|
||||
span.text-nowrap BenchCoach
|
||||
.text-center.lead.fst-italic.fw-light
|
||||
| An assistant coach for TeamSnap
|
||||
.row
|
||||
.col.text-center
|
||||
ul.list-group
|
||||
each team in teams
|
||||
a(class='team list-group-item' href=`/${team.id}/home`) #{team.name} [#{team.seasonName}]
|
||||
@@ -1,84 +0,0 @@
|
||||
html
|
||||
head
|
||||
meta(charset='utf-8')
|
||||
meta(name='viewport' content='width=device-width, initial-scale=1')
|
||||
title BenchCoach - Teams
|
||||
link(rel='stylesheet' href='/css/bootstrap.min.css')
|
||||
link(rel='stylesheet' href='/font/bootstrap-icons.min.css')
|
||||
link(rel='stylesheet' href='/css/teamsnap-ui.css')
|
||||
script(type='text/javascript', src='/js/teamsnap.js')
|
||||
|
||||
body
|
||||
.container
|
||||
.Panel
|
||||
.Panel-header
|
||||
.Panel-title Upload
|
||||
.Panel-body
|
||||
.Panel-row
|
||||
.input-group
|
||||
label(for='file') Select file
|
||||
input(id='file' type="file")
|
||||
input(id="csrf_token", type="hidden" name="csrf_token" value=`${csrf_token}`)
|
||||
input(id='team_id', type="hidden", value=`${team_id}`)
|
||||
input(id='opponent_id', type="hidden", value=`${opponent_id}`)
|
||||
input(id='token', type="hidden", value=`${token}`)
|
||||
input(id='clientId', type="hidden", value=`${clientId}`)
|
||||
button(type='submit' onClick="submitForm()") Upload
|
||||
|
||||
script.
|
||||
function submitForm(e) {
|
||||
console.log(document.getElementById("opponent_id").value)
|
||||
const file = document.getElementById("file");
|
||||
const csrf_token = document.getElementById("csrf_token").value;
|
||||
const team_id = document.getElementById("team_id").value;
|
||||
const opponent_id = document.getElementById("opponent_id").value;
|
||||
const formData = new FormData();
|
||||
formData.append("file", file.files[0]);
|
||||
formData.append("team_id", team_id);
|
||||
formData.append("opponent_id", opponent_id);
|
||||
for (var key of formData.entries()) {
|
||||
console.log(key[0] + ', ' + key[1]);
|
||||
}
|
||||
fetch(`/${team_id}/opponent/${opponent_id}/upload-logo`, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
"X-CSRF-Token": csrf_token,
|
||||
|
||||
}
|
||||
})
|
||||
.then((res) => console.log(res))
|
||||
.catch((err) => ("Error occured", err));
|
||||
}
|
||||
|
||||
function uploadImageForm(e) {
|
||||
const file = document.getElementById("file");
|
||||
const csrf_token = document.getElementById("csrf_token").value;
|
||||
const team_id = document.getElementById("team_id").value;
|
||||
const opponent_id = document.getElementById("opponent_id").value;
|
||||
const token = document.getElementById("token").value;
|
||||
const clientId = document.getElementById("clientId").value;
|
||||
const formData = new FormData();
|
||||
teamsnap.init(clientId);
|
||||
teamsnap.auth(token)
|
||||
console.log(teamsnap.isAuthed())
|
||||
teamsnap
|
||||
.loadCollections()
|
||||
.then(() => {
|
||||
return teamsnap.createTeamMedium({
|
||||
file: file.files[0],
|
||||
mediaFormat: "file",
|
||||
memberId: member_id,
|
||||
teamId: team_id,
|
||||
teamMediaGroupId: "4927028",
|
||||
description: `team-logo-${opponent_id}.png`,
|
||||
});
|
||||
})
|
||||
.then((item) => {
|
||||
return teamsnap.uploadTeamMedium(item);
|
||||
})
|
||||
.then((item) => {
|
||||
res.send("Data Received: " + JSON.stringify(item));
|
||||
})
|
||||
.fail((err) => console.log(err));
|
||||
}
|
||||
Reference in New Issue
Block a user