diff --git a/app/controllers/Clas.scala b/app/controllers/Clas.scala index dba51ce516..76e131490c 100644 --- a/app/controllers/Clas.scala +++ b/app/controllers/Clas.scala @@ -211,25 +211,26 @@ final class Clas( Ok(_) } else WithClassAndStudents(me, id) { (clas, students) => - ctx.req.flash.get("created").map(_ split ' ').?? { - case Array(userId, password) => - env.clas.api.student - .get(clas, userId) - .map2(lila.clas.Student.WithPassword(_, lila.user.User.ClearPassword(password))) - case _ => fuccess(none) - } flatMap { created => - env.clas.forms.student.generate map { createForm => - Ok( - html.clas.student.form( - clas, - students, - env.clas.forms.student.invite(clas), - createForm, - created - ) - ) + for { + created <- ctx.req.flash.get("created").map(_ split ' ').?? { + case Array(userId, password) => + env.clas.api.student + .get(clas, userId) + .map2(lila.clas.Student.WithPassword(_, lila.user.User.ClearPassword(password))) + case _ => fuccess(none) } - } + nbStudents <- env.clas.api.student.count(clas.id) + createForm <- env.clas.forms.student.generate + } yield Ok( + html.clas.student.form( + clas, + students, + env.clas.forms.student.invite(clas), + createForm, + nbStudents, + created + ) + ) } } @@ -241,14 +242,17 @@ final class Clas( .bindFromRequest()(ctx.body) .fold( err => - BadRequest( - html.clas.student.form( - clas, - students, - env.clas.forms.student.invite(clas), - err + env.clas.api.student.count(clas.id) map { nbStudents => + BadRequest( + html.clas.student.form( + clas, + students, + env.clas.forms.student.invite(clas), + err, + nbStudents + ) ) - ).fuccess, + }, data => env.clas.api.student.create(clas, data, me) map { case (user, password) => @@ -268,14 +272,17 @@ final class Clas( .bindFromRequest()(ctx.body) .fold( err => - BadRequest( - html.clas.student.form( - clas, - students, - err, - env.clas.forms.student.create + env.clas.api.student.count(clas.id) map { nbStudents => + BadRequest( + html.clas.student.form( + clas, + students, + err, + env.clas.forms.student.create, + nbStudents + ) ) - ).fuccess, + }, data => env.user.repo named data.username flatMap { _ ?? { user => diff --git a/app/views/clas/student.scala b/app/views/clas/student.scala index a5c64de112..9138a7d66a 100644 --- a/app/views/clas/student.scala +++ b/app/views/clas/student.scala @@ -113,11 +113,21 @@ object student { students: List[Student], invite: Form[_], create: Form[_], + nbStudents: Int, created: Option[lila.clas.Student.WithPassword] = none )(implicit ctx: Context) = bits.layout(trans.clas.addStudent.txt(), Left(c withStudents students))( cls := "box-pad student-add", - h1(trans.clas.addStudent()), + h1( + trans.clas.addStudent(), + s" ($nbStudents/${lila.clas.Clas.maxStudents})" + ), + nbStudents > (lila.clas.Clas.maxStudents / 2) option p(dataIcon := "", cls := "text")( + s"Note that a class can have up to ${lila.clas.Clas.maxStudents} students.", + "To manage more students, ", + a(href := routes.Clas.studentForm(c.id.value))("create more classes"), + "." + ), created map { case Student.WithPassword(student, password) => flashMessage(cls := "student-add__created")( @@ -134,51 +144,47 @@ object student { ) }, standardFlash(), - div(cls := "student-add__choice")( - div(cls := "info")( - h2(trans.clas.inviteALichessAccount()), - p(trans.clas.inviteDesc1()), - p(trans.clas.inviteDesc2()), - p( - strong(trans.clas.inviteDesc3()), - br, - trans.clas.inviteDesc4() + (nbStudents <= lila.clas.Clas.maxStudents) option frag( + div(cls := "student-add__choice")( + div(cls := "info")( + h2(trans.clas.inviteALichessAccount()), + p(trans.clas.inviteDesc1()), + p(trans.clas.inviteDesc2()), + p( + strong(trans.clas.inviteDesc3()), + br, + trans.clas.inviteDesc4() + ) + ), + postForm(cls := "form3", action := routes.Clas.studentInvite(c.id.value))( + form3.group(invite("username"), trans.clas.lichessUsername())( + form3.input(_, klass = "user-autocomplete")(created.isEmpty option autofocus)(dataTag := "span") + ), + realNameField(invite), + form3.submit("Invite", icon = none) ) ), - postForm(cls := "form3", action := routes.Clas.studentInvite(c.id.value))( - form3.group(invite("username"), trans.clas.lichessUsername())( - form3.input(_, klass = "user-autocomplete")(created.isEmpty option autofocus)(dataTag := "span") + div(cls := "student-add__or")("~ or ~"), + div(cls := "student-add__choice")( + div(cls := "info")( + h2(trans.clas.createANewLichessAccount()), + p(trans.clas.createDesc1()), + p(trans.clas.createDesc2()), + p(strong(trans.clas.createDesc3()), br, trans.clas.createDesc4()) ), - realNameField(invite), - form3.submit("Invite", icon = none) - ) - ), - div(cls := "student-add__or")("~ or ~"), - div(cls := "student-add__choice")( - div(cls := "info")( - h2(trans.clas.createANewLichessAccount()), - p(trans.clas.createDesc1()), - p( - trans.clas.createDesc2() - ), - p( - strong(trans.clas.createDesc3()), - br, - trans.clas.createDesc4() + postForm(cls := "form3", action := routes.Clas.studentCreate(c.id.value))( + form3.group( + create("create-username"), + trans.clas.lichessUsername(), + help = a(cls := "name-regen", href := s"${routes.Clas.studentForm(c.id.value)}?gen=1")( + trans.clas.generateANewUsername() + ).some + )( + form3.input(_)(created.isDefined option autofocus) + ), + realNameField(create, "create-realName"), + form3.submit(trans.signUp(), icon = none) ) - ), - postForm(cls := "form3", action := routes.Clas.studentCreate(c.id.value))( - form3.group( - create("create-username"), - trans.clas.lichessUsername(), - help = a(cls := "name-regen", href := s"${routes.Clas.studentForm(c.id.value)}?gen=1")( - trans.clas.generateANewUsername() - ).some - )( - form3.input(_)(created.isDefined option autofocus) - ), - realNameField(create, "create-realName"), - form3.submit(trans.signUp(), icon = none) ) ) ) diff --git a/modules/clas/src/main/Clas.scala b/modules/clas/src/main/Clas.scala index ba4ca6a118..dbd8df8464 100644 --- a/modules/clas/src/main/Clas.scala +++ b/modules/clas/src/main/Clas.scala @@ -26,6 +26,8 @@ case class Clas( object Clas { + val maxStudents = 100 + def make(teacher: User, name: String, desc: String) = Clas( _id = Id(scala.util.Random.alphanumeric take 8 mkString), name = name, diff --git a/modules/clas/src/main/ClasApi.scala b/modules/clas/src/main/ClasApi.scala index 6316aad9ad..ef682b833c 100644 --- a/modules/clas/src/main/ClasApi.scala +++ b/modules/clas/src/main/ClasApi.scala @@ -122,6 +122,8 @@ final class ClasApi( } } + def count(clasId: Clas.Id): Fu[Int] = coll.countSel($doc("clasId" -> clasId)) + def isManaged(user: User): Fu[Boolean] = coll.exists($doc("userId" -> user.id, "managed" -> true))