limit students per class

This commit is contained in:
Thibault Duplessis 2020-04-08 19:58:57 -05:00
parent 3bafda3c4b
commit 1fac7c5ecf
4 changed files with 91 additions and 74 deletions

View file

@ -211,25 +211,26 @@ final class Clas(
Ok(_) Ok(_)
} else } else
WithClassAndStudents(me, id) { (clas, students) => WithClassAndStudents(me, id) { (clas, students) =>
ctx.req.flash.get("created").map(_ split ' ').?? { for {
case Array(userId, password) => created <- ctx.req.flash.get("created").map(_ split ' ').?? {
env.clas.api.student case Array(userId, password) =>
.get(clas, userId) env.clas.api.student
.map2(lila.clas.Student.WithPassword(_, lila.user.User.ClearPassword(password))) .get(clas, userId)
case _ => fuccess(none) .map2(lila.clas.Student.WithPassword(_, lila.user.User.ClearPassword(password)))
} flatMap { created => case _ => fuccess(none)
env.clas.forms.student.generate map { createForm =>
Ok(
html.clas.student.form(
clas,
students,
env.clas.forms.student.invite(clas),
createForm,
created
)
)
} }
} 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) .bindFromRequest()(ctx.body)
.fold( .fold(
err => err =>
BadRequest( env.clas.api.student.count(clas.id) map { nbStudents =>
html.clas.student.form( BadRequest(
clas, html.clas.student.form(
students, clas,
env.clas.forms.student.invite(clas), students,
err env.clas.forms.student.invite(clas),
err,
nbStudents
)
) )
).fuccess, },
data => data =>
env.clas.api.student.create(clas, data, me) map { env.clas.api.student.create(clas, data, me) map {
case (user, password) => case (user, password) =>
@ -268,14 +272,17 @@ final class Clas(
.bindFromRequest()(ctx.body) .bindFromRequest()(ctx.body)
.fold( .fold(
err => err =>
BadRequest( env.clas.api.student.count(clas.id) map { nbStudents =>
html.clas.student.form( BadRequest(
clas, html.clas.student.form(
students, clas,
err, students,
env.clas.forms.student.create err,
env.clas.forms.student.create,
nbStudents
)
) )
).fuccess, },
data => data =>
env.user.repo named data.username flatMap { env.user.repo named data.username flatMap {
_ ?? { user => _ ?? { user =>

View file

@ -113,11 +113,21 @@ object student {
students: List[Student], students: List[Student],
invite: Form[_], invite: Form[_],
create: Form[_], create: Form[_],
nbStudents: Int,
created: Option[lila.clas.Student.WithPassword] = none created: Option[lila.clas.Student.WithPassword] = none
)(implicit ctx: Context) = )(implicit ctx: Context) =
bits.layout(trans.clas.addStudent.txt(), Left(c withStudents students))( bits.layout(trans.clas.addStudent.txt(), Left(c withStudents students))(
cls := "box-pad student-add", 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 { created map {
case Student.WithPassword(student, password) => case Student.WithPassword(student, password) =>
flashMessage(cls := "student-add__created")( flashMessage(cls := "student-add__created")(
@ -134,51 +144,47 @@ object student {
) )
}, },
standardFlash(), standardFlash(),
div(cls := "student-add__choice")( (nbStudents <= lila.clas.Clas.maxStudents) option frag(
div(cls := "info")( div(cls := "student-add__choice")(
h2(trans.clas.inviteALichessAccount()), div(cls := "info")(
p(trans.clas.inviteDesc1()), h2(trans.clas.inviteALichessAccount()),
p(trans.clas.inviteDesc2()), p(trans.clas.inviteDesc1()),
p( p(trans.clas.inviteDesc2()),
strong(trans.clas.inviteDesc3()), p(
br, strong(trans.clas.inviteDesc3()),
trans.clas.inviteDesc4() 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))( div(cls := "student-add__or")("~ or ~"),
form3.group(invite("username"), trans.clas.lichessUsername())( div(cls := "student-add__choice")(
form3.input(_, klass = "user-autocomplete")(created.isEmpty option autofocus)(dataTag := "span") 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), postForm(cls := "form3", action := routes.Clas.studentCreate(c.id.value))(
form3.submit("Invite", icon = none) form3.group(
) create("create-username"),
), trans.clas.lichessUsername(),
div(cls := "student-add__or")("~ or ~"), help = a(cls := "name-regen", href := s"${routes.Clas.studentForm(c.id.value)}?gen=1")(
div(cls := "student-add__choice")( trans.clas.generateANewUsername()
div(cls := "info")( ).some
h2(trans.clas.createANewLichessAccount()), )(
p(trans.clas.createDesc1()), form3.input(_)(created.isDefined option autofocus)
p( ),
trans.clas.createDesc2() realNameField(create, "create-realName"),
), form3.submit(trans.signUp(), icon = none)
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)
) )
) )
) )

View file

@ -26,6 +26,8 @@ case class Clas(
object Clas { object Clas {
val maxStudents = 100
def make(teacher: User, name: String, desc: String) = Clas( def make(teacher: User, name: String, desc: String) = Clas(
_id = Id(scala.util.Random.alphanumeric take 8 mkString), _id = Id(scala.util.Random.alphanumeric take 8 mkString),
name = name, name = name,

View file

@ -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] = def isManaged(user: User): Fu[Boolean] =
coll.exists($doc("userId" -> user.id, "managed" -> true)) coll.exists($doc("userId" -> user.id, "managed" -> true))