initial commit

This commit is contained in:
2023-09-07 14:23:30 -05:00
commit 857aa1af52
213 changed files with 5930 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
- pct_going = (availability_summary.player_going_count.to_f/team.player_member_count.to_f)*100.0
- pct_maybe = (availability_summary.player_maybe_count.to_f/team.player_member_count.to_f)*100.0
- pct_not_going = (availability_summary.player_not_going_count.to_f/team.player_member_count.to_f)*100.0
- pct_unknown = (availability_summary.player_unknown_count.to_f/team.player_member_count.to_f)*100.0
.progress
div id="availability-bar-player-going-count-#{event.id}" class="progress-bar availability-bar going" role="progressbar" style="width:#{pct_going}%"
= availability_summary.player_going_count
div id="availability-bar-player-maybe-count-#{event.id}" class="progress-bar availability-bar maybe" role="progressbar" style="width:#{pct_maybe}%"
= availability_summary.player_maybe_count
div id="availability-bar-player-not-going-count-#{event.id}" class="progress-bar availability-bar not-going" role="progressbar" style="width:#{pct_not_going}%"
= availability_summary.player_not_going_count
div id="availability-bar-player-unknown-count-#{event.id}" class="progress-bar availability-bar unknown" role="progressbar" style="width:#{pct_unknown}%"
= availability_summary.player_unknown_count

View File

@@ -0,0 +1,53 @@
.Panel-expandableRow.lineup-slot
=form.hidden_field name="[event_lineup_entries][][label]", value: !event_lineup_entry.nil? ? event_lineup_entry['label'] : nil
=form.hidden_field name="[event_lineup_entries][][sequence]", value: !event_lineup_entry.nil? ? event_lineup_entry['sequence'] : nil
=form.hidden_field name="[event_lineup_entries][][member_id]", value: member.id
=form.hidden_field name="[event_lineup_entries][][event_id]", value: event.id
=form.hidden_field name="[event_lineup_entries][][id]", value: !event_lineup_entry.nil? ? event_lineup_entry['id'] : nil
=form.hidden_field name="[event_lineup_entries][][availability_status_code]", value: availability.status_code
=form.hidden_field name="[event_lineup_entries][][member][last_name]", value: member.last_name
=form.hidden_field name="[event_lineup_entries][][member][first_name]", value: member.first_name
=form.hidden_field name="[event_lineup_entries][][member][jersey_number]", value: member.jersey_number
=form.hidden_field name="[event_lineup_entries][][member][email_addresses]", value: member.email_addresses
- if event_lineup_entry
- selected_position, flags = extract_flags(event_lineup_entry)
div.u-hidden #{selected_position} #{flags}
- else
- selected_position = "--"
.Panel-row.Panel-row--withCells.Panel-row--parent
.Panel-cell.Panel-cell--header.u-padXs.u-sizeFit
a.Panel-expandableControl onclick="this.classList.toggle('is-expanded');this.closest('.Panel-expandableRow').querySelector('.Panel-childRows').classList.toggle('is-expanded')"
<span class="Panel-expandableControlIcon">
<svg viewBox="0 0 960 960" class="Icon"><path d="M497 854c-6.7 6.7-14.7 10-24 10H225c-14.7 0-24.7-6.3-30-19-2-4-3-8.3-3-13 0-7.3 2.7-14.3 8-21l313-331-313-330c-9.3-11.3-11-23-5-35 6-12.7 16-19 30-19h248c10 0 18 3.7 24 11l326 352c6 6 9 13 9 21s-3 15.3-9 22L497 854z"/></svg>
</span>
.u-flexAlignSelfCenter.Panel-expandableControl
div.sequence.u-textNoWrap style="width:2ch;"
div(class="Panel-cell u-padXs u-size6of12 u-xs-size8of12.u-sm-size10of12 d-block")
div class="d-flex availability-status-code-#{availability.status_code}"
div
span.lastname #{member.last_name}
span.lastname.u-hidden.u-md-inline , #{member.first_name}
span.jerseynumber.u-hidden.u-md-inline ##{member.jersey_number}
.Panel-cell.u-padXs.u-size3of12.u-xs-size2of12.u-sm-size1of12
.SelectBox.position-selection
select(onchange="onPositionSelectChange(this)" class="position-select-box SelectBox-options")
=options_for_select ["--", "P", "C", "1B", "2B", "3B", "SS", "LF", "CF", "RF", "EH", "DH"], selected_position
.Panel-cell.u-padXs.u-flexAlignSelfCenter.u-size1of12
.drag-handle
i.bi.bi-grip-vertical.text-secondary.drag-handle
.Panel-childRows
.Panel-row.Panel-row--withCells
- for timeline_i in [*4.downto(1).to_a,*5...9]
- unless timeline[timeline_i].nil? or timeline[timeline_i][:event].nil?
.Panel-cell.u-padXs
.span.u-textDecorationNone class="Tooltip Tooltip--text" data-tooltip="#{timeline[timeline_i][:event].formatted_title}"
| #{timeline[timeline_i][:event].start_date.strftime("%a, %-m/%-d")}
.Panel-row.Panel-row--withCells
- for timeline_i in [*4.downto(1).to_a,*5...9]
- unless timeline[timeline_i].nil? or timeline[timeline_i][:event].nil?
- availability_in_timeline = timeline[timeline_i][:by_member][member][:availability]
- lineup_entry_in_timeline = timeline[timeline_i][:by_member][member][:event_lineup_entry]
.Panel-cell.u-padXs class="availability-status-code-#{availability_in_timeline.status_code}"
small style="font-size:10px;" #{lineup_entry_in_timeline.nil? ? "": lineup_entry_in_timeline.label}

View File

@@ -0,0 +1,710 @@
=stylesheet_link_tag 'gamecard', media: 'all'
body(class="B5")
#page-1.sheet.gamecard
section#todays-game
.grid-container
.section-header
#todays-game-header.bar-left.event-title
| G#00-XX at Team 00/00/20XX 0:00 XM
.bar-right.homeaway
| Axxx
.bar-span.gametitle
#offense-pane.left
table#starting-lineup-offense
tbody
- for i in 1...11
tr
th[rowspan="2"]
| #{i}
td#offense-slot-2-name.player-name
| Lastname
td#offense-slot-2-jersey-number.jersey-number
| 00
td#offense-slot-2-position.position
| XX
tr
td
td
td
#defense-pane.right
.container
.field-container
image[src="../baseball-diamond.svg"]
.row[style="justify-content: center"]
.defense-slot-set
table
tr
th.position
| CF
td#defense-slot-CF-name.player-name
| player
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
| player
tr
td[colspan="2"]
tr
td[colspan="2"]
.defense-slot-set
table
tr
th.position
| RF
td#defense-slot-RF-name.player-name
| player
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
| player
tr
td[colspan="2"]
tr
td[colspan="2"]
.defense-slot-set
table
tr
th.position
| 2B
td#defense-slot-2B-name.player-name
| player
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
| player
tr
td[colspan="2"]
tr
td[colspan="2"]
.defense-slot-set
table
tr
th.position
| 1B
td#defense-slot-1B-name.player-name
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
| player
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
| player
td.position
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 (15|1)
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
th.today-plus-1
.rotate
| MON
th.today-plus-2
.rotate
| TUE
th.today-plus-3
.rotate
| WED
th.today-plus-4
.rotate
| THU
th.today-minus-1
.rotate
| MON
th.today-minus-2
.rotate
| TUE
th.today-minus-3
.rotate
| WED
th.today-minus-4
.rotate
| THU
tbody
- for i in 1...26
tr id="roster-history-slot-#{i}"
td.is-present-checkbox
span
| ■
td.jersey-number.border-left
| XX
td.player-name
| 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
| ?
td.position-capability.catcher
| ?
td.position-capability.infield
| ?
td.position-capability.outfield
| ?
td.availability.future.today-plus-1
| U
td.availability.future.today-plus-2
| U
td.availability.future.today-plus-3
| U
td.availability.future.today-plus-4
| U
td.availability.past.today-minus-1
| U
td.availability.past.today-minus-2
| U
td.availability.past.today-minus-3
| U
td.availability.past.today-minus-4
| U
tfoot
tr
th[colspan="3"]
th
th[colspan="4"]
th.today-plus-1
.rotate
th.today-plus-2
.rotate
th.today-plus-3
.rotate
th.today-plus-4
.rotate
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
| GAME
.bar-right.homeaway
.starting-lineup-table
table
thead
tr
th[colspan="4"]
| Starting
tbody
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
.substitution-table
table[style="width: 100%"]
thead
tr
th
| Substitution
tbody
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
section#lineup-card-exchange.lineup-card
.grid-container
.section-header.event-title
| GAME
.starting-lineup-table
table.starting-lineup-table
thead
tr
th
th.player-name
| Name
th.jersey-number
| Num
th.position
| Pos
tbody
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
#page-2.sheet.gamecard
section#back-cover
section#front-cover
p
span.event-label
br
span.opponent
br
span.event-date
br
span.event-time
br
span.event-location-name
br
span.homeaway
br
section#lineup-card-dugout-empty.lineup-card
.grid-container
.section-header
.starting-lineup-table
table
thead
tr
th[colspan="4"]
| Starting
tbody
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
.substitution-table
table[style="width: 100%"]
thead
tr
th
| Substitution
tbody
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
tr
td.substitution
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
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
tr
th.sequence.label
td.player-name
td.jersey-number
td.position

View File

@@ -0,0 +1,386 @@
=stylesheet_link_tag 'gamecard', media: 'all'
body(class="B5")
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.formatted_title}
| #{event.start_date}
| #{event.start_date}
.bar-right.homeaway #{event.game_type}
.bar-span.gametitle
#offense-pane.left
table#starting-lineup-offense
tbody
- for i in 0...11
- if (event_lineup_entries_offense[i])?)
tr
th(rowspan='2') #{i+1}
td(id="offense-slot-#{i}-name" class="player-name") #{event_lineup_entries_offense[i].member.last_name}
td(id="offense-slot-#{i}-jersey-number" class="jersey-number") #{event_lineup_entries_offense[i].member.jersey_number}
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.last_name}
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.last_name}
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.last_name}
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.last_name}
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.last_name}
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.last_name}
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.last_name}
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.last_name}
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.last_name}
td.jersey-number
| #{(event_lineup_entries.find((lue)=>lue.label.startsWith("P")) || {"member":{}}).member.jersey_number}
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 (
| #{availability_summaries.find((e)=>e.id==event.id).player_going_count}|
| #{availability_summaries.find((e)=>e.id==event.id).player_maybe_count}
| )
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
- for event_future, i in events_future
th(id="avail-header-today-plus-#{i+1}" class="availability future")
.rotate #{event_future.start_date}
- for event_past, i in events_past
th(id="avail-header-today-minus-#{i+1}" class="availability past")
.rotate #{event_past.start_date}
tbody
- for row, index in availabilities.filter((e)=>e.event.id==event.id && !e.member.is_non_player)
tr(id="roster-history-slot-#{index+1}" class="")
td(class="is-present-checkbox available-status-code-#{row.status_code}")
span &#x25A0;
td(
class="jersey-number border-left available-status-code-#{row.status_code} #{event_lineup_entries.find((lue)=>lue.member.id==row.member.id) !== undefined ? "starting" : ""}")
| #{row.member.jersey_number}
td(
class="player-name available-status-code-#{row.status_code} #{event_lineup_entries.find((lue)=>lue.member.id==row.member.id) !== undefined ? "starting" : ""}")
| #{row.member.last_name}
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_lineup_entry
- for future_event, i in events_future
- future_availability = availabilities.find((el)=>el.event.id ==future_event.id && el.memberId==row.member.id)
- future_lineup_entry = all_lineup_entries.find((el)=>el.event.id ==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 availabilityavailable-status-code-#{future_availability.status_code}")
if future_lineupEntry
|#{future_lineupEntry.label.slice(0,2)}
else
|#{future_availability.status[0]}
- var past_availability
- var past_lineupEntry
- for past_event, i in events_past
- past_availability = availabilities.find((el)=>el.event.id==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 availabilityavailable-status-code-#{past_availability.status_code}#{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')
- for event_future, i in events_future
th(class="availability future")
.rotate #{availabilitySummaries.find((el)=>el.event.id == 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.game_type}
.starting-lineup-table
table
thead
tr
th(colspan='4') Starting
tbody
- for 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.last_name}
td.jersey-number #{event_lineup_entries_offense[i].member.jersey_number}
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
- for i in 0...11
tr
td.substitution
tr
td.substitution
section#lineup-card-exchange.lineup-card
.grid-container
.section-header.event-title #{event.formatted_title_for_multi_team}
.starting-lineup-table
table.starting-lineup-table
thead
tr
th
th.player-name Name
th.jersey-number Num
th.position Pos
tbody
- for i in 0...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.last_name}
td.jersey-number #{event_lineup_entries_offense[i].member.jersey_number}
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.game_type}
.event-title
| #{event.startDate},
| #{event.startDate}
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
- for _ in 0...12
tr
th.sequence.label
td.player-name
td.jersey-number
td.position
.substitution-table
table(style='width: 100%')
thead
tr
th Substitution
tbody
- for _ in 0...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
- for _ in 0...12
tr
th.sequence.label
td.player-name
td.jersey-number
td.position

View File

@@ -0,0 +1,103 @@
div id="messages"
#success-message.Feedback.Feedback--positive.u-hidden role="alert"
.Feedback-icon
i.Icon.bi.bi-hand-thumbs-up-fill.u-fontSizeXl
h5.headline Successful
span.message
p
a href="javascript:void(0)" onclick="javascript:this.closest('.Feedback').classList.add('u-hidden')" Dismiss
#failure-message.Feedback.Feedback--negative.u-hidden role="alert"
.Feedback-icon.bi.bi-hand-thumbs-down-fill
h5.headline Not Successful!
span.message Error encountered.
p
a href="javascript:void(0)" onclick="javascript:this.closest('.Feedback').classList.add('u-hidden')" Dismiss
#waiting-message.Feedback.u-hidden role="alert"
.Feedback-icon
.Icon.Icon--loader.u-colorForeground.u-fontSizeXl
<svg viewBox="0 0 66 66" role="presentation" class="Icon Icon--loader">
<circle fill="none" stroke-width="12" stroke="currentColor" stroke-linecap="round" cx="33" cy="33" r="24" />
</svg>
h5.headline Sending...
div id="modals"
#email-modal.Modal
.Modal-content
.Modal-header
.Modal-title Email
a href="javascript:void(0)" onclick="javascript:this.closest('.Modal').classList.toggle('is-open')" Dismiss
.Modal-body
div id="event-lineup-#{event.id}" class="event-lineup"
= form_with(url: url_for(event_lineup_submit_path :team_id=>team.id, :event_id=>event.id), method: :post, :html => { :onsubmit => "onSubmit(this,event)" }) do |form|
=form.hidden_field name="event_lineup_id", value: !event_lineup.nil? ? event_lineup.id : nil
.event-card.u-maxWidthSm
.event-card-body
div.Grid
div.Grid-cell.u-sizeFill
h3.title #{event.formatted_title}
div.Grid-cell.u-sizeFit
.ButtonGroup
= form.submit("Save", class: "Button Button--orange")
.Button.Button--orange.u-padSidesXs.Popup onclick="togglePopup(this)"
.bi.bi-caret-down.u-spaceNone
.Popup-container.Popup-container--down.Popup-container--rightHang data-popup="demo4a" style="width: 200px"
.Popup-content
.u-textBold
a href="javascript:void(0)" onclick="emailModal(this, '#{url_for(event_lineup_email_path :team_id=>team.id, :event_id=>event.id)}')"
i.bi.bi-envelope
span Generate Email
hr.Divider.u-spaceEndsNone
a href=""
p.u-padEndsSm.u-padSidesMd Action 2
div.date #{event.start_date.strftime("%a, %b %e, %l:%M %p")}
div.location #{event.location_name}
div.availability-bar=render("event/availability_bar", team:team, event:event, availability_summary: availability_summary)
.Panel.u-maxWidthSm.starting
.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
- for pos in ["P", "C", "1B", "2B", "3B", "SS", "LF", "CF", "RF", "EH", "DH"]
.Grid-cell.position-status #{pos}
.slot-set
- event_lineup_entry.select{|d| extract_flags(d)[1].exclude?(PositionLabelFlag::POSITION_ONLY)}.sort_by{|d| d['sequence']}.each_with_index do |d|
- m = members.find{|m| m.id == d['member_id']}
=render("lineup_slot",event_lineup_entry: by_member[m][:event_lineup_entry],availability: by_member[m][:availability], member:m, event:event, timeline: timeline, form: form, event_lineup:d)
.Panel.u-maxWidthSm.position-only
.Panel-body
.Panel-row.Panel-title.u-padXs
i.bi.bi-clipboard-check.me-1
span Position Only
.slot-set
- event_lineup_entry.select{ |d| extract_flags(d)[1].include?(PositionLabelFlag::POSITION_ONLY)}.sort_by{|d| d['sequence']}.each_with_index do |d|
- m = members.find{|m| m.id == d['member_id']}
=render("lineup_slot",event_lineup_entry: by_member[m][:event_lineup_entry],availability: by_member[m][:availability], member:m, event:event, timeline: timeline, form: form, event_lineup:d)
.Panel.u-maxWidthSm.bench
.Panel-body
.Panel-row.Panel-title.u-padXs
i.bi.bi-clipboard-minus.me-1
span Bench
.slot-set
- by_member.select{|m,d| !d[:availability].status_code.nil? and d[:availability].status_code != 0 and !m.is_non_player and d[:event_lineup_entry].nil?}.each_with_index do |(m, d), i|
=render("lineup_slot",event_lineup_entry: by_member[m][:event_lineup_entry],availability: by_member[m][:availability], member:m, event:event, timeline: timeline, form: form, event_lineup:event_lineup)
.Panel.u-maxWidthSm.out
.Panel-body
.Panel-row.Panel-title.u-padXs
i.bi.bi-clipboard-x.me-1
span Out
.slot-set
- by_member.select{|m,d| (d[:availability].status_code.nil? or d[:availability].status_code == 0) and !m.is_non_player and d[:event_lineup_entry].nil?}.each_with_index do |(m, d), i|
=render("lineup_slot",event_lineup_entry: by_member[m][:event_lineup_entry],availability: by_member[m][:availability], member:m, event:event, timeline: timeline, form: form, event_lineup:event_lineup)
script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"
=javascript_include_tag 'lineup'
javascript:
colorPositions();
refreshLineupOrder();

View File

@@ -0,0 +1,232 @@
=stylesheet_link_tag 'gamecard', media: 'all'
body.B5
#page-1.sheet.gamecard
section#todays-game
header
.event-title.float-left
| #{event.formatted_title} #{event.start_date.strftime("%a, %b %e %l:%M %p")}
.homeaway.float-right
| #{event.game_type}
.grid-container
#offense-pane
table#starting-lineup-offense
tbody
.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
tr.slot
th.sequence(rowspan="2")
| #{i+1}
td.player-name
| #{member.last_name}
td.jersey-number
| #{member.jersey_number}
td.position
| #{d[:event_lineup_entry].label}
tr.slot.substitute
td
td
td
#defense-pane
.field-container
img[src="/assets/baseball-diamond.svg"]
- for pos in ["CF", "LF", "RF", "SS", "2B", "3B", "1B", "C"]
- (member, d) = by_member.find{|m,d| d[:event_lineup_entry] and d[:event_lineup_entry].label == pos}
div class="slot-set pos-slot-#{pos}"
table
tbody
tr.slot
th.position
td.player-name
| #{member.last_name}
tr.slot.substitute
th
td
tr.slot.substitute
th
td
- (member, d) = by_member.find{|m,d| d[:event_lineup_entry] and (d[:event_lineup_entry].label == "P" or d[:event_lineup_entry].label == "P [PO]")}
div class="slot-set pos-slot-p"
table
tr
th.position
td.player-name #{!member.nil? ? member.last_name : ""}
td.jersey-number #{!member.nil? ? member.jersey_number : ""}
td.jersey-number
tr
th.position.pos-slot-rp-1
td.player-name
td.jersey-number
td.jersey-number
tr
th.position.pos-slot-rp-2
td.player-name
td.jersey-number
td.jersey-number
.footer
table.notes
tbody
tr
th
| Notes
tr
td
tr
td
tr
td
section#roster-and-history
div
table
thead
tr
th#today-availability[colspan="3"]
| Available (#{availability_summary.player_going_count}|#{availability_summary.player_maybe_count})
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
- for timepoint, i in timeline.select{|tp| tp[:comparison_to_selected]>0}.sort{|tp| -tp[:comparison_to_selected]}.each_with_index
th class="avail-today-plus-#{timepoint[:comparison_to_selected]} future availability"
div
| #{timepoint[:event].start_date.strftime("%a")}
- for timepoint, i in timeline.select{|tp| tp[:comparison_to_selected]<0}.sort{|tp| tp[:comparison_to_selected]}.each_with_index
th class="avail-today-minus-#{timepoint[:comparison_to_selected].abs} past availability available-status-code-#{timepoint[:by_member][member][:availability].status_code}"
div
| #{timepoint[:event].start_date.strftime("%a")}
tbody
- by_member.select{|m,d| !m.is_non_player}.each_with_index do |(member, d), i|
tr id="roster-history-slot-#{i}"
td class="is-present-checkbox available-status-code-#{d[:availability].status_code}"
span
| ■
td class="jersey-number border-left available-status-code-#{d[:availability].status_code} #{!d[:event_lineup_entry].nil? ? 'starting' : ''}"
| #{member.jersey_number}
td class="player-name available-status-code-#{d[:availability].status_code} #{!d[:event_lineup_entry].nil? ? 'starting' : ''}"
| #{member.last_name}
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
| #{member.position.split(",",-1).include?("P") ? "\u2713" : ""}
td.position-capability.catcher
| #{member.position.split(",",-1).include?("C") ? "\u2713" : ""}
td.position-capability.infield
| #{member.position.split(",",-1).include?("IF") ? "\u2713" : ""}
td.position-capability.outfield
| #{member.position.split(",",-1).include?("OF") ? "\u2713" : ""}
- for timepoint, i in timeline.select{|tp| tp[:comparison_to_selected]>0}.sort{|tp| -tp[:comparison_to_selected]}.each_with_index
td class="avail-today-plus-#{timepoint[:comparison_to_selected]} future availability available-status-code-#{timepoint[:by_member][member][:availability].status_code}"
| #{timepoint[:by_member][member][:event_lineup_entry] ? timepoint[:by_member][member][:event_lineup_entry].label : timepoint[:by_member][member][:availability].status[0]}
- for timepoint, i in timeline.select{|tp| tp[:comparison_to_selected]<0}.sort{|tp| -tp[:comparison_to_selected]}.each_with_index
td class="avail-today-minus-#{timepoint[:comparison_to_selected].abs} past availability available-status-code-#{timepoint[:by_member][member][:availability].status_code}"
| #{timepoint[:by_member][member][:event_lineup_entry] ? timepoint[:by_member][member][:event_lineup_entry].label : timepoint[:by_member][member][:availability].status[0]}
-for section_name in ["lineup-card-dugout", "lineup-card-exchange"]
section.lineup-card id="#{section_name}"
header
.float-left.event-title
| #{event.formatted_title}
.float-right.homeaway
| #{event.game_type}
.starting-lineup-table
table
thead
tr
th[colspan="4"]
| Starting
th.substitution
| Substitution
tbody
- 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}
- num_entries = offensive_lineup_entries.length
- for i in (0...12)
tr.slot
th.sequence
| #{i<num_entries ? i+1 : nil}
td.player-name
| #{i<num_entries ? offensive_lineup_entries[i][0].last_name : nil}
td.jersey-number
| #{i<num_entries ? offensive_lineup_entries[i][0].jersey_number : nil}
td.position
| #{i<num_entries ? offensive_lineup_entries[i][1][:event_lineup_entry].label : nil}
td.substitution
#page-2.sheet.gamecard
section#back-cover
section#front-cover
header
.float-left.homeaway
| #{event.game_type[0]}
.event-title
| #{event.start_date.strftime('%A %b %-d, %l:%M %P')}
br
| #{event.location_name}
.container
.team
| #{team.name}
div vs.
.opponent
| #{event.opponent_name}
-for section_name in ["lineup-card-dugout-blank", "lineup-card-exchange-blank"]
section.lineup-card id="#{section_name}"
header
.float-left.event-title
.float-right.homeaway
.starting-lineup-table
table
thead
tr
th[colspan="4"]
| Starting
th.substitution
| Substitution
tbody
- for i in (0...12)
tr.slot
th.sequence
td.player-name
td.jersey-number
td.position
td.substitution

View File

@@ -0,0 +1,320 @@
=stylesheet_link_tag 'gamecard', media: 'all'
body.B5
#page-1.sheet.gamecard
section#todays-game
header
.event-title.float-left
| G#00 vs. XXX Xxx, Xxx 00 0:00 XM
.homeaway.float-right
| Hxxx
.grid-container
#offense-pane.left
table#starting-lineup-offense
tbody
.slot-set
- for i in 1...11
tr.slot
th.sequence(rowspan="2")
| #{i}
td.player-name
| Lastname
td.jersey-number
| 00
td.position
| XX
tr.slot.substitute
td
td
td
#defense-pane
.field-container
img[src="/assets/baseball-diamond.svg"]
- for pos in ["cf", "lf", "rf", "ss", "second", "third", "first", "catcher"]
div class="slot-set #{pos}"
table
tbody
tr.slot
th.position
td.player-name
| Lastname
tr.slot.substitute
th
td
tr.slot.substitute
th
td
div class="slot-set pitcher"
table
tr
th.position
| P
td.player-name
| player
td.jersey-number
td.jersey-number
tr
th.position.relief-pitcher
| RP
td.player-name
td.jersey-number
td.jersey-number
tr
th.position.relief-pitcher
| RP
td.player-name
td.jersey-number
td.jersey-number
.footer
table.notes
tbody
tr
th
| Notes
tr
td
tr
td
tr
td
section#roster-and-history
div
table
thead
tr
th#today-availability[colspan="3"]
| Available (00|0)
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
th#avail-header-today-plus-1.availability.future
.rotate
| Sun
th#avail-header-today-plus-2.availability.future
.rotate
| Tue
th#avail-header-today-plus-3.availability.future
.rotate
| Sun
th#avail-header-today-plus-4.availability.future
.rotate
| Sun
th#avail-header-today-minus-1.availability.past
.rotate
| Tue
th#avail-header-today-minus-2.availability.past
.rotate
| Sun
th#avail-header-today-minus-3.availability.past
.rotate
| Tue
th#avail-header-today-minus-4.availability.past
.rotate
| Sun
tbody
- for i in 1...24
tr id="roster-history-slot-#{i}"
td.is-present-checkbox.available-status-code-1
span
| ■
td.jersey-number.border-left.available-status-code-1.starting
| 00
td.player-name.available-status-code-1.starting
| 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
| ✓
td.position-capability.catcher
| ✓
td.position-capability.infield
| ✓
td.position-capability.outfield
| ✓
td#avail--today-plus-1.row.future.availability.available-status-code-
| X
td#avail-xx-today-plus-2.row.future.availability.available-status-code-
| X
td#avail-xx-today-plus-3.row.future.availability.available-status-code-
| X
td#avail-xx-today-plus-4.row.future.availability.available-status-code-
| X
td#avail-xx-today-minus-1.row.past.availability.available-status-code-.started
| X
td#avail-xx-today-minus-2.row.past.availability.available-status-code-
| X
td#avail-xx-today-minus-3.row.past.availability.available-status-code-
| X
td#avail-xx-today-minus-4.row.past.availability.available-status-code-
| X
section#lineup-card-dugout.lineup-card
.grid-container
header
.float-left.event-title
| G#XX vs. Xxxxxx
.float-right.homeaway
| Xxxx
.starting-lineup-table
table
thead
tr
th[colspan="4"]
| Starting
tbody
- for i in 1...13
tr
th.sequence
| #{i}
td.player-name
| Lastname
td.jersey-number
| XX
td.position
| XX
.substitution-table
table[style="width: 100%"]
thead
tr
th
| Substitution
tbody
- for i in 1...13
tr
td.substitution
tr
td.substitution
section#lineup-card-exchange.lineup-card
.grid-container
header.event-title
| Xxxxx G#XX vs. Xxxxxx
.starting-lineup-table
table.starting-lineup-table
thead
tr
th
th.player-name
| Name
th.jersey-number
| Num
th.position
| Pos
tbody
- for i in 1...13
tr
th.sequence
| #{i}
td.player-name
| Lastname
td.jersey-number
| XX
td.position
| XX
#page-2.sheet.gamecard
section#back-cover
section#front-cover
header
.float-right.homeaway
| Xxxx
.event-title
| XXXXXX, XXX 00, 0:00 XM
br
| XXXXX Park
.container
.team
| Xxxxx
div vs.
.opponent
| Xxxxx
section#lineup-card-dugout-blank.lineup-card
.grid-container
header
.starting-lineup-table
table
thead
tr
th[colspan="4"]
| Starting
tbody
- for i in 1...13
tr
th.sequence
td.player-name
td.jersey-number
td.position
.substitution-table
table
thead
tr
th
| Substitution
tbody
- for i in 1...13
tr
td.substitution
tr
td.substitution
section#lineup-card-exchange-blank.lineup-card
.grid-container
header
.starting-lineup-table
table.starting-lineup-table
thead
tr
th
th.player-name
| Name
th.jersey-number
| Num
th.position
| Pos
tbody
- for i in 1...13
tr
th.sequence
td.player-name
td.jersey-number
td.position

View File

@@ -0,0 +1,84 @@
css:
.lineup-email {
font-family: "Helvaetica", sans-serif;
}
h3 {
font-family: inherit;
font-weight: bold;
color: white;
}
.title-cell {
font-weight:bold;
background-color:#323669;
color:#fff;
padding:2px 5px;
}
.title-cell.out {
background-color: rgb(244, 199, 195);
color: black;
}
.sequence-cell {
font-weight:bold;
padding:2px 5px;
}
.name-cell {
width:200px;
}
.lineup-email
table
thead
tr
th.title-cell colSpan=3
| STARTING LINEUP
tbody
- for entry in event_lineup_entries.select{|e| !e[:label].blank? and extract_flags(e)[1].exclude?(PositionLabelFlag::POSITION_ONLY)}
tr
td.sequence-cell
| #{entry[:sequence].to_i+1}
td.name-cell
| #{entry[:member][:last_name]}, #{entry[:member][:first_name]} ##{entry[:member][:jersey_number]}
td
| #{entry[:label]}
tr
th.title-cell colSpan=3 Starting (Pos. Only)
- for entry in event_lineup_entries.select{|e| !e[:label].blank? and extract_flags(e)[1].include?(PositionLabelFlag::POSITION_ONLY)}
tr
td.sequence-cell
td.name-cell
| #{entry[:member][:last_name]}, #{entry[:member][:first_name]} - ##{entry[:member][:jersey_number]}
td
| #{extract_flags(entry)[0]}
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

View File

@@ -0,0 +1,15 @@
.Panel
.Panel-header
.Panel-title Schedule
.Panel-body
- for event in events
a.Panel-row--withCells.u-textDecorationNone.u-colorInfo href=url_for( event_path :team_id=>team.id, :event_id=>event.id)
.Panel-cell
|#{event.formatted_title}
.Panel-cell
|#{event.start_date.strftime("%a %b %e")}
.Panel-cell
|#{event.start_date.strftime("%l:%M %p")}
.Panel-cell
|#{event.location_name}

View File

@@ -0,0 +1,23 @@
div.event-card
div.event-card-body
h3.title #{event.formatted_title}
div.date #{event.start_date.strftime("%a, %b %e, %l:%M %p")}
div.location #{event.location_name}
div.availability-bar=render("event/availability_bar", team:team, event:event, availability_summary: availability_summary)
div.event-card-footer.Grid
div.Grid-cell.u-sizeFill
a.Button href=url_for(event_path :team_id=>team.id, :event_id=>event.id)
i.bi.bi-calendar
span.u-hidden.u-xs-inline Details
div.Grid-cell.u-sizeFill
a(class="Button" href=url_for(event_lineup_path :team_id => team.id, :event_id => event.id))
i(class="bi bi-clipboard")
span.u-hidden.u-xs-inline Lineup
div.Grid-cell.u-sizeFill
a(class="Button" href=url_for(event_lineup_card_path :team_id => team.id, :event_id => event.id))
i(class="bi bi-book")
span.u-hidden.u-xs-inline Card
div.Grid-cell.u-sizeFill
a(class="Button" href="https://go.teamsnap.com/#{team.id}/schedule/view_game/#{event.id}")
i(class="bi bi-asterisk")
span.u-hidden.u-xs-inline TeamSnap

View File

@@ -0,0 +1,32 @@
doctype html
html
head
title BenchCoach
meta name="viewport" content="width=device-width, initial-scale=1.0"
= csrf_meta_tags
= csp_meta_tag
= stylesheet_link_tag "application", "data-turbo-track": "reload", media: 'all'
link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.3.0/font/bootstrap-icons.css"
link rel="stylesheet" type="text/css" href="https://teamsnap-ui.teamsnap.com/css/teamsnap-ui.css"
link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous"
link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css"
= javascript_importmap_tags
body.bg-light
header.Header
.Header-container.Grid.u-flexAlignItemsCenter
.Grid-cell.u-sizeFill
.Header-banner.Grid.u-flexAlignItemsCenter
.Grid-cell.u-sizeFit
span.Header-bannerLogo
img(src='/assets/benchcoach.svg' alt='BenchCoach Logo' width='30' height='30')
.Grid-cell.u-sizeFill
- if defined?(team)
h1.Header-bannerTitle #{team.name}
- else
h1.Header-bannerTitle BenchCoach
.Grid-cell.u-sizeFit
.u-spaceSm.u-md-spaceLg
= yield

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
/* Email styles need to be inline */
</style>
</head>
<body>
<%= yield %>
</body>
</html>

View File

@@ -0,0 +1 @@
<%= yield %>

View File

View File

@@ -0,0 +1,3 @@
h1 Welcome #{@user["first_name"]}
a href=url_for(team_list_path) Dashboard

View File

@@ -0,0 +1,5 @@
h1 Opponents
- for opponent in opponents
a.Panel-cell href=url_for( opponent_path :team_id=>team.id, :opponent_id=>opponent.id)
li #{opponent.name}

View File

@@ -0,0 +1,36 @@
.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 class="Button" onclick="navigator.clipboard.writeText('#{opponent.id}');"
i.bi.bi-clipboard.Icon
.Panel-row.Panel-row--withCells
.Panel-cell.Panel-cell--header Contact Name
.panel-cell #{opponent.contacts_name}
.Panel-row.Panel-row--withCells
.Panel-cell.Panel-cell--header Contact Phone
.panel-cell #{opponent.contacts_phone}
.Panel-row.Panel-row--withCells
.Panel-cell.Panel-cell--header Contact Email
.panel-cell #{opponent.contacts_email}
.Panel-row.Panel-row--withCells
.Panel-cell.Panel-cell--header Logo
.panel-cell
- if opponent_logo
img(src="#{opponent_logo.medium_url}" width="64" height="64")
a class="Button" target="_blank" rel="noopener noreferrer" href="https://go.teamsnap.com/#{team.id}/files/view/#{opponent_logo.id}"
i class="bi bi-asterisk Icon"
- else
- if opponent_logo.team_media_group.id
a class="Button" target="_blank" rel="noopener noreferrer" href="https://go.teamsnap.com/#{team.id}/files/list/#{opponent_logo.team_media_group.id}" Upload
- else
a class="Button" target="_blank" rel="noopener noreferrer" href="https://go.teamsnap.com/#{team.id}/files/" Upload
Button class="Button" onclick="navigator.clipboard.writeText('opponent-logo-#{opponent.id}.png')"
i.bi.bi-clipboard.Icon
span Copy Filename
.Panel-row.Panel-row--withCells
.Panel-cell.Panel-cell--header Notes
.panel-cell #{opponent.notes}

View File

@@ -0,0 +1,9 @@
= form_with url: "/#{team_id}/opponent/#{opponent_id}/upload_logo", method: :post do |form|
.Panel
.Panel-header
.Panel-title Upload
.Panel-body
.Panel-row.Panel-row--withCells
.Panel-cell.Panel-cell--header = form.label :file, "Select file"
.Panel-cell = form.file_field :file
.Panel-cell = form.submit "Submit", class: 'Button'

View File

@@ -0,0 +1,16 @@
= form_tag '/auth/teamsnap', method: :post, data: {turbo: false} do
.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
= submit_tag "TeamSnap", class: "Button Button--large Button--orange u-spaceSidesAuto"
.Grid-cell.u-size7of12.u-textCenter
h1
img(src="/assets/benchcoach.svg" style="width: 2.5em;")
h1
strong
| Welcome to
span.text-nowrap BenchCoach
.lead.fst-italic.fw-light
| An assistant coach for TeamSnap

View File

@@ -0,0 +1,21 @@
.Panel.u-sm-size1of2.u-spaceSidesAuto.u-spaceSm.u-maxWidthSm
.Panel-header
h3.Panel-title My Teams
.Panel-body
- for team in teams
- if !team.is_archived_season
a.Panel-row.Panel-row--withCells.u-textDecorationNone href="#{url_for team_path :team_id=>team.id }"
.Panel-cell.u-flexGrow1
b #{team.name}
.Panel-cell.u-fontSizeSm.u-size1of3.u-textRight
| #{team.season_name}
.Panel-row.Panel-row--header
| Archived Seasons
- for team in teams
- if team.is_archived_season
a.Panel-row.Panel-row--withCells.u-textDecorationNone href="#{url_for team_path :team_id=>team.id }"
.Panel-cell.u-flexGrow1
b #{team.name}
.Panel-cell.u-fontSizeSm.u-size1of3.u-textRight
| #{team.season_name}

View File

@@ -0,0 +1,50 @@
h2 #{team.name}
p #{team.season_name}
div.u-spaceBottomMd
a.Button.u-spaceSidesXs href="#{url_for event_list_path}"
<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
a.Button.u-spaceSidesXs 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
a.Button.u-spaceSidesXs href="#{url_for opponent_list_path}"
<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
div.u-maxWidthSm
.Panel
.Panel-header
h2.Panel-title Upcoming Events
.Panel-body.u-padSm
- for event in upcoming_events
div.event-card
div.event-card-body
h3.title #{event.formatted_title}
div.date #{event.start_date.strftime("%a, %b %e, %l:%M %p")}
div.location #{event.location_name}
div.availability-bar.fullwidth=render("event/availability_bar", team:team, event:event, availability_summary: availability_summaries.find{|a| a.id==event.id})
div.event-card-footer.Grid
div.Grid-cell.u-sizeFill
a.Button href=url_for(event_path :team_id=>team.id, :event_id=>event.id)
i.bi.bi-calendar
span.u-hidden.u-xs-inline Details
div.Grid-cell.u-sizeFill
a(class="Button" href=url_for(event_lineup_path :team_id => team.id, :event_id => event.id))
i(class="bi bi-clipboard")
span.u-hidden.u-xs-inline Lineup
div.Grid-cell.u-sizeFill
a(class="Button" href=url_for(event_lineup_card_path :team_id => team.id, :event_id => event.id))
i(class="bi bi-book")
span.u-hidden.u-xs-inline Card
div.Grid-cell.u-sizeFill
a(class="Button" href="https://go.teamsnap.com/#{team.id}/schedule/view_game/#{event.id}")
i(class="bi bi-asterisk")
span.u-hidden.u-xs-inline TeamSnap
.Panel
.Panel-header
h3.Panel-title Past Events
.Panel-body
ul
- for event in past_events
li #{event.formatted_title}