class student real name WIP
parent
104b7d99a0
commit
9fd53a3c9e
|
@ -104,8 +104,8 @@ final class Clas(
|
|||
err
|
||||
)
|
||||
).fuccess,
|
||||
username =>
|
||||
env.clas.api.student.create(clas, username, t) map {
|
||||
data =>
|
||||
env.clas.api.student.create(clas, data, t) map {
|
||||
case (user, password) =>
|
||||
Redirect(routes.Clas.studentShow(clas.id.value, user.username))
|
||||
.flashing("password" -> password.value)
|
||||
|
@ -129,8 +129,8 @@ final class Clas(
|
|||
env.clas.forms.student.create
|
||||
)
|
||||
).fuccess,
|
||||
username =>
|
||||
env.user.repo named username flatMap {
|
||||
data =>
|
||||
env.user.repo named data.username flatMap {
|
||||
_ ?? { user =>
|
||||
env.clas.api.student.invite(clas, user, t) inject
|
||||
Redirect(routes.Clas.studentForm(clas.id.value)).flashSuccess
|
||||
|
|
|
@ -6,7 +6,7 @@ import lila.api.Context
|
|||
import lila.app.templating.Environment._
|
||||
import lila.app.ui.ScalatagsTemplate._
|
||||
import lila.clas.{ Clas, Student }
|
||||
import lila.clas.ClasForm.Data
|
||||
import lila.clas.ClasForm.ClasData
|
||||
import controllers.routes
|
||||
|
||||
object clas {
|
||||
|
@ -92,21 +92,21 @@ object clas {
|
|||
fragList(clas.teachers.toList.map(t => userIdLink(t.value.some)))
|
||||
)
|
||||
|
||||
def create(form: Form[Data])(implicit ctx: Context) =
|
||||
def create(form: Form[ClasData])(implicit ctx: Context) =
|
||||
bits.layout("New class", Right("newClass"))(
|
||||
cls := "box-pad",
|
||||
h1("New class"),
|
||||
innerForm(form, routes.Clas.create)
|
||||
)
|
||||
|
||||
def edit(c: lila.clas.Clas, form: Form[Data])(implicit ctx: Context) =
|
||||
def edit(c: lila.clas.Clas, form: Form[ClasData])(implicit ctx: Context) =
|
||||
bits.layout(c.name, Left(c))(
|
||||
cls := "box-pad",
|
||||
h1("Edit ", c.name),
|
||||
innerForm(form, routes.Clas.update(c.id.value))
|
||||
)
|
||||
|
||||
private def innerForm(form: Form[Data], url: play.api.mvc.Call)(implicit ctx: Context) =
|
||||
private def innerForm(form: Form[ClasData], url: play.api.mvc.Call)(implicit ctx: Context) =
|
||||
postForm(cls := "form3", action := url)(
|
||||
form3.globalError(form),
|
||||
form3.group(form("name"), frag("Class name"))(form3.input(_)(autofocus)),
|
||||
|
|
|
@ -142,7 +142,14 @@ object student {
|
|||
)
|
||||
)
|
||||
|
||||
def form(c: lila.clas.Clas, invite: Form[String], create: Form[String])(implicit ctx: Context) =
|
||||
private def realName(form: Form[_])(implicit ctx: Context) =
|
||||
form3.group(
|
||||
form("realName"),
|
||||
frag("Real name"),
|
||||
help = frag("Private info, never visible on Lichess. Helps you remember who that student is.").some
|
||||
)(form3.input(_))
|
||||
|
||||
def form(c: lila.clas.Clas, invite: Form[_], create: Form[_])(implicit ctx: Context) =
|
||||
bits.layout("Add student", Left(c))(
|
||||
cls := "box-pad student-add",
|
||||
h1("Add student"),
|
||||
|
@ -166,6 +173,7 @@ object student {
|
|||
form3.group(invite("invite"), frag("Invite username"))(
|
||||
form3.input(_, klass = "user-autocomplete")(autofocus)(dataTag := "span")
|
||||
),
|
||||
realName(invite),
|
||||
form3.submit("Invite")
|
||||
)
|
||||
),
|
||||
|
@ -186,6 +194,7 @@ object student {
|
|||
),
|
||||
postForm(cls := "form3", action := routes.Clas.studentCreate(c.id.value))(
|
||||
form3.group(create("username"), frag("Create username"))(form3.input(_)(autofocus)),
|
||||
realName(create),
|
||||
form3.submit(trans.signUp())
|
||||
)
|
||||
)
|
||||
|
|
|
@ -50,12 +50,12 @@ final class ClasApi(
|
|||
.sort($sort desc "viewedAt")
|
||||
.list[Clas]()
|
||||
|
||||
def create(data: ClasForm.Data, teacher: Teacher): Fu[Clas] = {
|
||||
def create(data: ClasForm.ClasData, teacher: Teacher): Fu[Clas] = {
|
||||
val clas = Clas.make(teacher, data.name, data.desc)
|
||||
coll.insert.one(clas) inject clas
|
||||
}
|
||||
|
||||
def update(from: Clas, data: ClasForm.Data): Fu[Clas] = {
|
||||
def update(from: Clas, data: ClasForm.ClasData): Fu[Clas] = {
|
||||
val clas = data update from
|
||||
coll.update.one($id(clas.id), clas) inject clas
|
||||
}
|
||||
|
@ -109,23 +109,27 @@ final class ClasApi(
|
|||
def isIn(clas: Clas, userId: User.ID): Fu[Boolean] =
|
||||
coll.exists($id(Student.id(userId, clas.id)))
|
||||
|
||||
def create(clas: Clas, username: String, teacher: Teacher.WithUser): Fu[(User, ClearPassword)] = {
|
||||
val email = EmailAddress(s"noreply.class.${clas.id}.$username@lichess.org")
|
||||
def create(
|
||||
clas: Clas,
|
||||
data: ClasForm.NewStudent,
|
||||
teacher: Teacher.WithUser
|
||||
): Fu[(User, ClearPassword)] = {
|
||||
val email = EmailAddress(s"noreply.class.${clas.id}.${data.username}@lichess.org")
|
||||
val password = Student.password.generate
|
||||
lila.mon.clas.studentCreate(teacher.user.id)
|
||||
userRepo
|
||||
.create(
|
||||
username = username,
|
||||
username = data.username,
|
||||
passwordHash = authenticator.passEnc(password),
|
||||
email = email,
|
||||
blind = false,
|
||||
mobileApiVersion = none,
|
||||
mustConfirmEmail = false
|
||||
)
|
||||
.orFail(s"No user could be created for $username")
|
||||
.orFail(s"No user could be created for ${data.username}")
|
||||
.flatMap { user =>
|
||||
userRepo.setKid(user, true) >>
|
||||
coll.insert.one(Student.make(user, clas, teacher.teacher.id, managed = true)) >>
|
||||
coll.insert.one(Student.make(user, clas, teacher.teacher.id, data.realName, managed = true)) >>
|
||||
sendWelcomeMessage(teacher, user, clas, s"$baseUrl/class/${clas.id}") inject
|
||||
(user -> password)
|
||||
}
|
||||
|
@ -139,7 +143,7 @@ final class ClasApi(
|
|||
}
|
||||
|
||||
private[ClasApi] def join(clas: Clas, user: User, teacherId: Teacher.Id): Fu[Student] = {
|
||||
val student = Student.make(user, clas, teacherId, managed = false)
|
||||
val student = Student.make(user, clas, teacherId, "", managed = false)
|
||||
coll.insert.one(student) inject student
|
||||
}
|
||||
|
||||
|
|
|
@ -15,26 +15,32 @@ final class ClasForm(
|
|||
mapping(
|
||||
"name" -> text(minLength = 3, maxLength = 100),
|
||||
"desc" -> text(minLength = 0, maxLength = 2000)
|
||||
)(Data.apply)(Data.unapply)
|
||||
)(ClasData.apply)(ClasData.unapply)
|
||||
)
|
||||
|
||||
def create = form
|
||||
|
||||
def edit(c: Clas) = form fill Data(
|
||||
def edit(c: Clas) = form fill ClasData(
|
||||
name = c.name,
|
||||
desc = c.desc
|
||||
)
|
||||
|
||||
object student {
|
||||
|
||||
def create = securityForms.signup.managed
|
||||
def create = Form(
|
||||
mapping(
|
||||
"username" -> securityForms.signup.username,
|
||||
"realName" -> nonEmptyText
|
||||
)(NewStudent.apply)(NewStudent.unapply)
|
||||
)
|
||||
|
||||
def invite = Form(
|
||||
single(
|
||||
"invite" -> lila.user.DataForm.historicalUsernameField.verifying("Unknown username", {
|
||||
mapping(
|
||||
"username" -> lila.user.DataForm.historicalUsernameField.verifying("Unknown username", {
|
||||
blockingFetchUser(_).isDefined
|
||||
})
|
||||
)
|
||||
}),
|
||||
"realName" -> nonEmptyText
|
||||
)(NewStudent.apply)(NewStudent.unapply)
|
||||
)
|
||||
|
||||
private def blockingFetchUser(username: String) =
|
||||
|
@ -44,7 +50,7 @@ final class ClasForm(
|
|||
|
||||
object ClasForm {
|
||||
|
||||
case class Data(
|
||||
case class ClasData(
|
||||
name: String,
|
||||
desc: String
|
||||
) {
|
||||
|
@ -53,4 +59,9 @@ object ClasForm {
|
|||
desc = desc
|
||||
)
|
||||
}
|
||||
|
||||
case class NewStudent(
|
||||
username: String,
|
||||
realName: String
|
||||
)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ case class Student(
|
|||
_id: Student.Id, // userId:clasId
|
||||
userId: User.ID,
|
||||
clasId: Clas.Id,
|
||||
realName: String,
|
||||
notes: String,
|
||||
managed: Boolean, // created for the class by the teacher
|
||||
created: Clas.Recorded,
|
||||
archived: Option[Clas.Recorded]
|
||||
|
@ -27,10 +29,12 @@ object Student {
|
|||
|
||||
def id(userId: User.ID, clasId: Clas.Id) = Id(s"${userId}:${clasId}")
|
||||
|
||||
def make(user: User, clas: Clas, teacherId: Teacher.Id, managed: Boolean) = Student(
|
||||
def make(user: User, clas: Clas, teacherId: Teacher.Id, realName: String, managed: Boolean) = Student(
|
||||
_id = id(user.id, clas.id),
|
||||
userId = user.id,
|
||||
clasId = clas.id,
|
||||
realName = realName,
|
||||
notes = "",
|
||||
managed = managed,
|
||||
created = Clas.Recorded(teacherId, DateTime.now),
|
||||
archived = none
|
||||
|
|
|
@ -52,7 +52,7 @@ final class DataForm(
|
|||
|
||||
object signup {
|
||||
|
||||
private val username = trimField(nonEmptyText)
|
||||
val username = trimField(nonEmptyText)
|
||||
.verifying(
|
||||
Constraints minLength 2,
|
||||
Constraints maxLength 20,
|
||||
|
@ -83,7 +83,7 @@ final class DataForm(
|
|||
|
||||
val website = Form(
|
||||
mapping(
|
||||
"username" -> trimField(username),
|
||||
"username" -> username,
|
||||
"password" -> text(minLength = 4),
|
||||
"email" -> withAcceptableDns(acceptableUniqueEmail(none)),
|
||||
"agreement" -> agreement,
|
||||
|
@ -94,17 +94,11 @@ final class DataForm(
|
|||
|
||||
val mobile = Form(
|
||||
mapping(
|
||||
"username" -> trimField(username),
|
||||
"username" -> username,
|
||||
"password" -> text(minLength = 4),
|
||||
"email" -> withAcceptableDns(acceptableUniqueEmail(none))
|
||||
)(MobileSignupData.apply)(_ => None)
|
||||
)
|
||||
|
||||
val managed = Form(
|
||||
single(
|
||||
"username" -> trimField(username)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val passwordReset = Form(
|
||||
|
@ -214,7 +208,7 @@ final class DataForm(
|
|||
|
||||
val reopen = Form(
|
||||
mapping(
|
||||
"username" -> nonEmptyText,
|
||||
"username" -> trimField(nonEmptyText),
|
||||
"email" -> sendableEmail, // allow unacceptable emails for BC
|
||||
"gameId" -> text,
|
||||
"move" -> text
|
||||
|
|
Loading…
Reference in New Issue