more coach form WIP
parent
6ab672ffa6
commit
a9153fd2b4
|
@ -1,13 +1,22 @@
|
|||
@(c: lila.coach.Coach.WithUser, form: Form[_])(implicit ctx: Context)
|
||||
|
||||
@group(field: play.api.data.Field, name: Html, half: Boolean = false)(html: Html) = {
|
||||
<div class="form-group@if(half){ half}@if(field.hasErrors){ has-error}">
|
||||
@import play.api.data.Field
|
||||
@import lila.coach.CoachForm.booleanChoices
|
||||
|
||||
@group(field: Field, name: Html, half: Boolean = false, largeLabel: Boolean = false)(html: Html) = {
|
||||
<div class="form-group@if(half){ half}@if(field.hasErrors){ has-error}@if(largeLabel){ large-label}">
|
||||
@html
|
||||
<label for="@field.id" class="control-label">@name</label>
|
||||
<i class="bar"></i>
|
||||
</div>
|
||||
}
|
||||
|
||||
@markdown(field: Field, name: Html) = {
|
||||
@group(field, name, largeLabel = true) {
|
||||
<textarea name="@field.name" id="@field.id">@field.value</textarea>
|
||||
}
|
||||
}
|
||||
|
||||
@moreCss = {
|
||||
@cssTag("material.form.css")
|
||||
@cssTag("coach.css")
|
||||
|
@ -17,12 +26,26 @@
|
|||
evenMoreCss = Some(cssTag("material.form.css"))) {
|
||||
<div class="coach_edit content_box small_box no_padding">
|
||||
<h1 class="lichess_title">
|
||||
Coach @userLink(c.user)
|
||||
@userLink(c.user) coach page
|
||||
</h1>
|
||||
<form class="content_box_content material form" action="@routes.Coach.edit" method="POST">
|
||||
@group(form("headline"), Html("Headline")) {
|
||||
@base.input(form("headline"))
|
||||
<div>
|
||||
@group(form("enabledByUser"), Html("Published in lichess coaches list"), half = true) {
|
||||
@base.select(form("enabledByUser"), booleanChoices)
|
||||
}
|
||||
@group(form("available"), Html("Currently available for lessons"), half = true) {
|
||||
@base.select(form("available"), booleanChoices)
|
||||
}
|
||||
</div>
|
||||
@group(form("profile.headline"), Html("Short and inspiring headline")) {
|
||||
@base.input(form("profile.headline"))
|
||||
}
|
||||
@markdown(form("profile.description"), Html("Who are you? <em>age, profession, country... let your students know you</em>"))
|
||||
@markdown(form("profile.playingExperience"), Html("Playing experience <em>tournaments played, best wins, other achievements</em>"))
|
||||
@markdown(form("profile.teachingExperience"), Html("Teaching experience <em>diplomas, years of practice, best student results</em>"))
|
||||
@markdown(form("profile.otherExperience"), Html("Other experiences <em>e.g. as chess commentator, or teaching other domains</em>"))
|
||||
@markdown(form("profile.skills"), Html("Best skills in chess and teaching"))
|
||||
@markdown(form("profile.methodology"), Html("Teaching methodology <em>How you prepare and run lessons. How you follow up with students.</em>"))
|
||||
<div class="button-container">
|
||||
<button type="submit" class="submit button text" data-icon="E">Save now</button>
|
||||
</div>
|
||||
|
|
|
@ -370,9 +370,9 @@ POST /inbox/$id<\w{8}>/delete controllers.Message.delete(id: String)
|
|||
|
||||
# Coach
|
||||
GET /coach controllers.Coach.index
|
||||
GET /coach/:username controllers.Coach.show(username: String)
|
||||
GET /coach/edit controllers.Coach.edit
|
||||
POST /coach/edit controllers.Coach.editApply
|
||||
GET /coach/:username controllers.Coach.show(username: String)
|
||||
|
||||
# Paste
|
||||
GET /paste controllers.Importer.importGame
|
||||
|
|
|
@ -48,5 +48,6 @@ private[api] final class Cli(bus: lila.common.Bus, renderer: ActorSelection) ext
|
|||
lila.blog.Env.current.cli.process orElse
|
||||
lila.study.Env.current.cli.process orElse
|
||||
lila.studySearch.Env.current.cli.process orElse
|
||||
lila.coach.Env.current.cli.process orElse
|
||||
process
|
||||
}
|
||||
|
|
|
@ -13,5 +13,5 @@ private[coach] object BsonHandlers {
|
|||
implicit val CoachProfileMarkdownBSONHandler = stringAnyValHandler[CoachProfile.Markdown](_.value, CoachProfile.Markdown.apply)
|
||||
implicit val CoachProfileBSONHandler = Macros.handler[CoachProfile]
|
||||
|
||||
implicit val CoachBSONHandler = Macros.handler[Coach]
|
||||
implicit val CoachBSONHandler = lila.db.BSON.LoggingHandler(logger)(Macros.handler[Coach])
|
||||
}
|
||||
|
|
|
@ -25,6 +25,14 @@ final class CoachApi(coll: Coll) {
|
|||
def update(c: Coach.WithUser, data: CoachForm.Data): Funit =
|
||||
coll.update($id(c.coach.id), data(c.coach)).void
|
||||
|
||||
def init(username: String): Fu[String] = find(username) flatMap {
|
||||
case Some(_) => fuccess(s"Coach $username already exists.")
|
||||
case None => UserRepo named username flatMap {
|
||||
case None => fuccess(s"No such username $username")
|
||||
case Some(user) => coll.insert(Coach make user) inject "Done!"
|
||||
}
|
||||
}
|
||||
|
||||
private def withUser(user: User)(coach: Coach): Coach.WithUser =
|
||||
Coach.WithUser(coach, user)
|
||||
}
|
||||
|
|
|
@ -9,25 +9,31 @@ object CoachForm {
|
|||
|
||||
def edit(coach: Coach) = Form(mapping(
|
||||
"hourlyRate" -> optional(number(min = 5, max = 500)),
|
||||
"available" -> optional(number),
|
||||
"enabledByUser" -> boolean,
|
||||
"available" -> boolean,
|
||||
"profile" -> profileMapping
|
||||
)(Data.apply)(Data.unapply)) fill Data(
|
||||
hourlyRate = coach.hourlyRate.map(_.value),
|
||||
available = coach.available.value option 1,
|
||||
enabledByUser = coach.enabledByUser.value,
|
||||
available = coach.available.value,
|
||||
profile = coach.profile)
|
||||
|
||||
case class Data(
|
||||
hourlyRate: Option[Int],
|
||||
available: Option[Int],
|
||||
enabledByUser: Boolean,
|
||||
available: Boolean,
|
||||
profile: CoachProfile) {
|
||||
|
||||
def apply(coach: Coach) = coach.copy(
|
||||
hourlyRate = hourlyRate.map(_ * 100) map Coach.Cents.apply,
|
||||
available = Coach.Available(available.isDefined),
|
||||
enabledByUser = Coach.Enabled(enabledByUser),
|
||||
available = Coach.Available(available),
|
||||
profile = profile,
|
||||
updatedAt = DateTime.now)
|
||||
}
|
||||
|
||||
val booleanChoices = Seq("true" -> "Yes", "false" -> "No")
|
||||
|
||||
private def profileMapping = mapping(
|
||||
"headline" -> optional(nonEmptyText(minLength = 5, maxLength = 140)),
|
||||
"description" -> optional(markdown),
|
||||
|
|
|
@ -16,6 +16,12 @@ final class Env(
|
|||
|
||||
lazy val api = new CoachApi(
|
||||
coll = coachColl)
|
||||
|
||||
def cli = new lila.common.Cli {
|
||||
def process = {
|
||||
case "coach" :: "init" :: username :: Nil => api init username
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object Env {
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
.coach_edit .material.form {
|
||||
margin: 30px 20px 20px 20px;
|
||||
}
|
||||
.coach_edit .material.form .form-group textarea {
|
||||
height: 8em;
|
||||
}
|
||||
.coach_edit .material.form .form-group.large-label {
|
||||
margin-top: 4.25rem;
|
||||
}
|
||||
.coach_edit .material.form .form-group.large-label .control-label {
|
||||
opacity: 0.8!important;
|
||||
top: -2rem!important;
|
||||
}
|
||||
.coach_edit .material.form .form-group.large-label .control-label em {
|
||||
opacity: 0.8;
|
||||
display: block;
|
||||
}
|
|
@ -92,6 +92,9 @@
|
|||
font-weight: normal;
|
||||
transition: all 0.28s ease;
|
||||
}
|
||||
.material.form .form-group .control-label em {
|
||||
transition: all 0.28s ease;
|
||||
}
|
||||
.material.form .form-group.no-label {
|
||||
margin-top: -1.5em;
|
||||
}
|
||||
|
@ -157,7 +160,8 @@ body.dark .material.form .form-group select option {
|
|||
outline: none;
|
||||
}
|
||||
.material.form .form-group *:focus ~ .control-label,
|
||||
.material.form .form-group *:focus ~ .control-label strong {
|
||||
.material.form .form-group *:focus ~ .control-label strong,
|
||||
.material.form .form-group *:focus ~ .control-label em {
|
||||
color: #3893E8;
|
||||
}
|
||||
.material.form .form-group *:focus ~ .bar::before {
|
||||
|
|
Loading…
Reference in New Issue