complete /class translation
This commit is contained in:
parent
f67b8cc2ce
commit
27b7675b95
|
@ -43,7 +43,7 @@ object topnav {
|
|||
),
|
||||
a(href := routes.Study.allDefault(1))(trans.studyMenu()),
|
||||
ctx.noKid option a(href := routes.Coach.allDefault(1))(trans.coaches()),
|
||||
canSeeClasMenu option a(href := routes.Clas.index)("Classes")
|
||||
canSeeClasMenu option a(href := routes.Clas.index)(trans.clas.lichessClasses())
|
||||
)
|
||||
),
|
||||
st.section(
|
||||
|
|
|
@ -21,7 +21,9 @@ private object bits {
|
|||
if (isGranted(_.Teacher))
|
||||
main(cls := "page-menu")(
|
||||
st.nav(cls := "page-menu__menu subnav")(
|
||||
a(cls := active.toOption.map(_.active("classes")), href := routes.Clas.index)("Lichess Classes"),
|
||||
a(cls := active.toOption.map(_.active("classes")), href := routes.Clas.index)(
|
||||
trans.clas.lichessClasses()
|
||||
),
|
||||
active.left.toOption.map { clas =>
|
||||
frag(
|
||||
a(cls := "active", href := routes.Clas.show(clas.clas.id.value))(clas.clas.name),
|
||||
|
@ -36,7 +38,9 @@ private object bits {
|
|||
}
|
||||
)
|
||||
} | {
|
||||
a(cls := active.toOption.map(_.active("newClass")), href := routes.Clas.form)("New class")
|
||||
a(cls := active.toOption.map(_.active("newClass")), href := routes.Clas.form)(
|
||||
trans.clas.newClass()
|
||||
)
|
||||
}
|
||||
),
|
||||
div(cls := "page-menu__content box")(body)
|
||||
|
@ -44,13 +48,8 @@ private object bits {
|
|||
else main(cls := "page-small box")(body)
|
||||
)
|
||||
|
||||
def showArchived(archived: Clas.Recorded) =
|
||||
div(
|
||||
"Archived by ",
|
||||
userIdLink(archived.by.value.some),
|
||||
" ",
|
||||
momentFromNowOnce(archived.at)
|
||||
)
|
||||
def showArchived(archived: Clas.Recorded)(implicit ctx: Context) =
|
||||
div(trans.clas.closedByXAtY(userIdLink(archived.by.value.some), momentFromNowOnce(archived.at)))
|
||||
|
||||
val sortNumberTh = th(attr("data-sort-method") := "number")
|
||||
val dataSort = attr("data-sort")
|
||||
|
|
|
@ -40,27 +40,27 @@ object clas {
|
|||
}
|
||||
|
||||
def teacherIndex(classes: List[Clas])(implicit ctx: Context) =
|
||||
bits.layout("Lichess Classes", Right("classes"))(
|
||||
bits.layout(trans.clas.lichessClasses.txt(), Right("classes"))(
|
||||
cls := "clas-index",
|
||||
div(cls := "box__top")(
|
||||
h1(trans.clas.lichessClasses()),
|
||||
a(
|
||||
href := routes.Clas.form,
|
||||
cls := "new button button-empty",
|
||||
title := "New Class",
|
||||
title := trans.clas.newClass.txt(),
|
||||
dataIcon := "O"
|
||||
)
|
||||
),
|
||||
if (classes.isEmpty)
|
||||
frag(hr, p(cls := "box__pad classes__empty")("No classes yet."))
|
||||
frag(hr, p(cls := "box__pad classes__empty")(trans.clas.noClassesYet()))
|
||||
else
|
||||
renderClasses(classes)
|
||||
)
|
||||
|
||||
def studentIndex(classes: List[Clas])(implicit ctx: Context) =
|
||||
bits.layout("Lichess Classes", Right("classes"))(
|
||||
bits.layout(trans.clas.lichessClasses.txt(), Right("classes"))(
|
||||
cls := "clas-index",
|
||||
div(cls := "box__top")(h1("Lichess Classes")),
|
||||
div(cls := "box__top")(h1(trans.clas.lichessClasses())),
|
||||
renderClasses(classes)
|
||||
)
|
||||
|
||||
|
@ -80,16 +80,17 @@ object clas {
|
|||
}
|
||||
)
|
||||
|
||||
def teachers(clas: Clas) =
|
||||
def teachers(clas: Clas)(implicit ctx: Context) =
|
||||
div(cls := "clas-teachers")(
|
||||
"Teachers: ",
|
||||
fragList(clas.teachers.toList.map(t => userIdLink(t.value.some)))
|
||||
trans.clas.teachersX(
|
||||
fragList(clas.teachers.toList.map(t => userIdLink(t.value.some)))
|
||||
)
|
||||
)
|
||||
|
||||
def create(form: Form[ClasData])(implicit ctx: Context) =
|
||||
bits.layout("New class", Right("newClass"))(
|
||||
bits.layout(trans.clas.newClass.txt(), Right("newClass"))(
|
||||
cls := "box-pad",
|
||||
h1("New class"),
|
||||
h1(trans.clas.newClass()),
|
||||
innerForm(form, none)
|
||||
)
|
||||
|
||||
|
@ -102,9 +103,8 @@ object clas {
|
|||
action := routes.Clas.archive(c.id.value, true),
|
||||
cls := "clas-edit__archive"
|
||||
)(
|
||||
form3.submit("Archive", icon = none)(
|
||||
cls := "confirm button-red button-empty",
|
||||
title := "Disband the class"
|
||||
form3.submit(trans.clas.closeClass(), icon = none)(
|
||||
cls := "confirm button-red button-empty"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -114,15 +114,15 @@ object clas {
|
|||
teacherDashboard.layout(c, students, "wall")(
|
||||
div(cls := "box-pad clas-wall__edit")(
|
||||
p(
|
||||
strong("Send a message to all students."),
|
||||
strong(trans.clas.sendAMessage()),
|
||||
br,
|
||||
"A link to the class will be automatically added at the end of the message, so you don't need to include it yourself."
|
||||
trans.clas.aLinkToTheClassWillBeAdded()
|
||||
),
|
||||
postForm(cls := "form3", action := routes.Clas.notifyPost(c.id.value))(
|
||||
form3.globalError(form),
|
||||
form3.group(
|
||||
form("text"),
|
||||
frag("Message")
|
||||
frag(trans.message())
|
||||
)(form3.textarea(_)(rows := 3)),
|
||||
form3.actions(
|
||||
a(href := routes.Clas.wall(c.id.value))(trans.cancel()),
|
||||
|
@ -135,24 +135,22 @@ object clas {
|
|||
private def innerForm(form: Form[ClasData], clas: Option[Clas])(implicit ctx: Context) =
|
||||
postForm(cls := "form3", action := clas.fold(routes.Clas.create())(c => routes.Clas.update(c.id.value)))(
|
||||
form3.globalError(form),
|
||||
form3.group(form("name"), frag("Class name"))(form3.input(_)(autofocus)),
|
||||
form3.group(form("name"), trans.clas.className())(form3.input(_)(autofocus)),
|
||||
form3.group(
|
||||
form("desc"),
|
||||
frag("Class description"),
|
||||
help = frag("Visible by both teachers and students of the class").some
|
||||
frag(trans.clas.classDescription()),
|
||||
help = trans.clas.visibleByBothStudentsAndTeachers().some
|
||||
)(form3.textarea(_)(rows := 5)),
|
||||
clas match {
|
||||
case None => form3.hidden(form("teachers"), ctx.userId)
|
||||
case Some(_) =>
|
||||
form3.group(
|
||||
form("teachers"),
|
||||
frag("Teachers of the class"),
|
||||
trans.clas.teachersOfTheClass(),
|
||||
help = frag(
|
||||
"Add Lichess usernames to invite them as teachers. One per line.",
|
||||
trans.clas.addLichessUsernames(),
|
||||
br,
|
||||
"All teachers must be ",
|
||||
a(href := routes.Clas.verifyTeacher)("vetted by Lichess"),
|
||||
" before being invited."
|
||||
trans.clas.theyMustFirstApply()
|
||||
).some
|
||||
)(form3.textarea(_)(rows := 4))
|
||||
},
|
||||
|
|
|
@ -25,10 +25,8 @@ object student {
|
|||
ctx.flash("password").map { password =>
|
||||
flashMessage(cls := "student-show__password")(
|
||||
div(
|
||||
p(
|
||||
"Make sure to copy or write down the password now. You won’t be able to see it again!"
|
||||
),
|
||||
pre(s"""Password: $password""")
|
||||
p(trans.clas.makeSureToCopy()),
|
||||
pre(trans.clas.passwordX(password))
|
||||
)
|
||||
)
|
||||
},
|
||||
|
@ -36,36 +34,33 @@ object student {
|
|||
div(cls := "student-show__archived archived")(
|
||||
bits.showArchived(archived),
|
||||
postForm(action := routes.Clas.studentArchive(clas.id.value, s.user.username, false))(
|
||||
form3.submit("Restore", icon = none)(
|
||||
cls := "confirm button-empty",
|
||||
title := "Get the student back into the class"
|
||||
)
|
||||
form3.submit(trans.clas.inviteTheStudentBack(), icon = none)(cls := "confirm button-empty")
|
||||
)
|
||||
)
|
||||
},
|
||||
s.student.notes.nonEmpty option div(cls := "student-show__notes")(richText(s.student.notes)),
|
||||
s.student.managed option div(cls := "student-show__managed")(
|
||||
p("This student account is managed"),
|
||||
p(trans.clas.thisStudentAccountIsManaged()),
|
||||
div(cls := "student-show__managed__actions")(
|
||||
postForm(action := routes.Clas.studentSetKid(clas.id.value, s.user.username, !s.user.kid))(
|
||||
form3.submit(if (s.user.kid) "Disable kid mode" else "Enable kid mode", icon = none)(
|
||||
form3.submit(if (s.user.kid) trans.disableKidMode() else trans.enableKidMode(), icon = none)(
|
||||
s.student.isArchived option disabled,
|
||||
cls := List("confirm button button-empty" -> true, "disabled" -> s.student.isArchived),
|
||||
title := "Kid mode prevents the student from communicating with Lichess players"
|
||||
title := trans.kidModeExplanation.txt()
|
||||
)
|
||||
),
|
||||
postForm(action := routes.Clas.studentResetPassword(clas.id.value, s.user.username))(
|
||||
form3.submit("Reset password", icon = none)(
|
||||
form3.submit(trans.clas.resetPassword(), icon = none)(
|
||||
s.student.isArchived option disabled,
|
||||
cls := List("confirm button button-empty" -> true, "disabled" -> s.student.isArchived),
|
||||
title := "Generate a new password for the student"
|
||||
title := trans.clas.generateANewPassword.txt()
|
||||
)
|
||||
),
|
||||
a(
|
||||
href := routes.Clas.studentRelease(clas.id.value, s.user.username),
|
||||
cls := "button button-empty",
|
||||
title := "Upgrade from managed to autonomous"
|
||||
)("Release")
|
||||
title := trans.clas.upgradeFromManaged.txt()
|
||||
)(trans.clas.release())
|
||||
)
|
||||
),
|
||||
views.html.activity(s.user, activities)
|
||||
|
@ -82,11 +77,10 @@ object student {
|
|||
),
|
||||
div(cls := "student-show__top__meta")(
|
||||
p(
|
||||
"Invited to ",
|
||||
a(href := routes.Clas.show(clas.id.value))(clas.name),
|
||||
" by ",
|
||||
userIdLink(s.student.created.by.value.some, withOnline = false),
|
||||
" ",
|
||||
trans.clas.invitedToXByY(
|
||||
a(href := routes.Clas.show(clas.id.value))(clas.name),
|
||||
userIdLink(s.student.created.by.value.some, withOnline = false)
|
||||
),
|
||||
momentFromNowOnce(s.student.created.at)
|
||||
),
|
||||
div(
|
||||
|
@ -97,11 +91,10 @@ object student {
|
|||
a(
|
||||
href := routes.Clas.studentEdit(clas.id.value, s.user.username),
|
||||
cls := "button button-empty"
|
||||
)("Edit"),
|
||||
)(trans.edit()),
|
||||
a(
|
||||
href := routes.User.show(s.user.username),
|
||||
cls := "button button-empty",
|
||||
title := "View full Lichess profile"
|
||||
cls := "button button-empty"
|
||||
)(trans.profile())
|
||||
)
|
||||
)
|
||||
|
@ -110,8 +103,8 @@ object student {
|
|||
private def realNameField(form: Form[_], fieldName: String = "realName")(implicit ctx: Context) =
|
||||
form3.group(
|
||||
form(fieldName),
|
||||
frag("Real name"),
|
||||
help = frag("Private. Will never be shown to anyone else. Helps you remember who that student is.").some
|
||||
trans.clas.realName(),
|
||||
help = trans.clas.privateWillNeverBeShown().some
|
||||
)(form3.input(_))
|
||||
|
||||
def form(
|
||||
|
@ -121,45 +114,41 @@ object student {
|
|||
create: Form[_],
|
||||
created: Option[lila.clas.Student.WithPassword] = none
|
||||
)(implicit ctx: Context) =
|
||||
bits.layout("Add student", Left(c withStudents students))(
|
||||
bits.layout(trans.clas.addStudent.txt(), Left(c withStudents students))(
|
||||
cls := "box-pad student-add",
|
||||
h1("Add student"),
|
||||
h1(trans.clas.addStudent()),
|
||||
p(
|
||||
"To ",
|
||||
a(href := routes.Clas.show(c.id.value))(c.name)
|
||||
),
|
||||
created map {
|
||||
case Student.WithPassword(student, password) =>
|
||||
flashMessage(cls := "student-add__created")(
|
||||
strong(
|
||||
"Lichess profile ",
|
||||
userIdLink(student.userId.some, withOnline = false),
|
||||
" created for ",
|
||||
student.realName,
|
||||
"."
|
||||
),
|
||||
p(
|
||||
"Make sure to copy or write down the password now. You won’t be able to see it again!"
|
||||
),
|
||||
pre(s"""Student: ${student.realName}
|
||||
Username: ${usernameOrId(student.userId)}
|
||||
Password: ${password.value}""")
|
||||
trans.clas.lichessProfileXCreatedForY(
|
||||
userIdLink(student.userId.some, withOnline = false),
|
||||
student.realName
|
||||
),
|
||||
p(trans.clas.makeSureToCopy()),
|
||||
pre(
|
||||
trans.clas.studentCredentials(student.realName, usernameOrId(student.userId), password.value)
|
||||
)
|
||||
)
|
||||
)
|
||||
},
|
||||
standardFlash(),
|
||||
div(cls := "student-add__choice")(
|
||||
div(cls := "info")(
|
||||
h2("Invite a Lichess account"),
|
||||
p("If the student already has a Lichess account, you can invite them to the class."),
|
||||
p("They will receive a message on Lichess with a link to join the class."),
|
||||
h2(trans.clas.inviteALichessAccount()),
|
||||
p(trans.clas.inviteDesc1()),
|
||||
p(trans.clas.inviteDesc2()),
|
||||
p(
|
||||
strong("Important: only invite students you know, and who actively want to join the class."),
|
||||
strong(trans.clas.inviteDesc3()),
|
||||
br,
|
||||
"Never send unsolicited invites to arbitrary players."
|
||||
trans.clas.inviteDesc4()
|
||||
)
|
||||
),
|
||||
postForm(cls := "form3", action := routes.Clas.studentInvite(c.id.value))(
|
||||
form3.group(invite("username"), frag("Lichess username"))(
|
||||
form3.group(invite("username"), trans.clas.lichessUsername())(
|
||||
form3.input(_, klass = "user-autocomplete")(created.isEmpty option autofocus)(dataTag := "span")
|
||||
),
|
||||
realNameField(invite),
|
||||
|
@ -169,24 +158,23 @@ Password: ${password.value}""")
|
|||
div(cls := "student-add__or")("~ or ~"),
|
||||
div(cls := "student-add__choice")(
|
||||
div(cls := "info")(
|
||||
h2("Create a new Lichess account"),
|
||||
p("If the student doesn't have a Lichess account yet, you can create one for them here."),
|
||||
h2(trans.clas.createANewLichessAccount()),
|
||||
p(trans.clas.createDesc1()),
|
||||
p(
|
||||
"No email address is required. A password will be generated, ",
|
||||
"and you will have to transmit it to the student, so they can log in."
|
||||
trans.clas.createDesc2()
|
||||
),
|
||||
p(
|
||||
strong("Important: a student must not have multiple accounts."),
|
||||
strong(trans.clas.createDesc3()),
|
||||
br,
|
||||
"If they already have one, use the invite form instead."
|
||||
trans.clas.createDesc4()
|
||||
)
|
||||
),
|
||||
postForm(cls := "form3", action := routes.Clas.studentCreate(c.id.value))(
|
||||
form3.group(
|
||||
create("create-username"),
|
||||
frag("Lichess username"),
|
||||
trans.clas.lichessUsername(),
|
||||
help = a(cls := "name-regen", href := s"${routes.Clas.studentForm(c.id.value)}?gen=1")(
|
||||
"Generate a new username"
|
||||
trans.clas.generateANewUsername()
|
||||
).some
|
||||
)(
|
||||
form3.input(_)(created.isDefined option autofocus)
|
||||
|
@ -206,7 +194,7 @@ Password: ${password.value}""")
|
|||
postForm(cls := "form3", action := routes.Clas.studentUpdate(clas.id.value, s.user.username))(
|
||||
form3.globalError(form),
|
||||
realNameField(form),
|
||||
form3.group(form("notes"), raw("Notes"), help = frag("Only visible to the class teachers").some)(
|
||||
form3.group(form("notes"), trans.notes(), help = trans.clas.onlyVisibleToTeachers().some)(
|
||||
form3.textarea(_)(autofocus, rows := 15)
|
||||
),
|
||||
form3.actions(
|
||||
|
@ -220,9 +208,8 @@ Password: ${password.value}""")
|
|||
action := routes.Clas.studentArchive(clas.id.value, s.user.username, true),
|
||||
cls := "student-show__archive"
|
||||
)(
|
||||
form3.submit("Archive", icon = none)(
|
||||
cls := "confirm button-red button-empty",
|
||||
title := "Remove the student from the class"
|
||||
form3.submit(trans.clas.removeStudent(), icon = none)(
|
||||
cls := "confirm button-red button-empty"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -236,20 +223,18 @@ Password: ${password.value}""")
|
|||
cls := "student-show student-edit",
|
||||
top(clas, s),
|
||||
div(cls := "box__pad")(
|
||||
h2("Release the account so the student can manage it in autonomy."),
|
||||
h2(trans.clas.releaseTheAccount()),
|
||||
p(
|
||||
"A released account cannot be made managed again. The student will be able to toggle kid mode and reset paswword themselves.",
|
||||
trans.clas.releaseDesc1(),
|
||||
br,
|
||||
"The student will remain in the class after their account is released."
|
||||
trans.clas.releaseDesc2()
|
||||
),
|
||||
postForm(cls := "form3", action := routes.Clas.studentReleasePost(clas.id.value, s.user.username))(
|
||||
form3.globalError(form),
|
||||
form3.group(
|
||||
form("email"),
|
||||
trans.email(),
|
||||
help = frag(
|
||||
"Real, unique email address of the student. We will send a confirmation email to it, with a link to release the account."
|
||||
).some
|
||||
help = trans.clas.realUniqueEmail().some
|
||||
)(form3.input(_, typ = "email")(autofocus, required)),
|
||||
form3.actions(
|
||||
a(href := routes.Clas.studentShow(clas.id.value, s.user.username))(trans.cancel()),
|
||||
|
|
|
@ -31,7 +31,7 @@ object studentDashboard {
|
|||
table(cls := "slist slist-pad teachers")(
|
||||
thead(
|
||||
tr(
|
||||
th("Teachers"),
|
||||
th(trans.clas.nbTeachers(teachers.size)),
|
||||
th,
|
||||
th
|
||||
)
|
||||
|
@ -68,10 +68,10 @@ object studentDashboard {
|
|||
table(cls := "slist slist-pad sortable")(
|
||||
thead(
|
||||
tr(
|
||||
th(attr("data-sort-default") := "1")("Students"),
|
||||
sortNumberTh("Rating"),
|
||||
sortNumberTh("Games"),
|
||||
sortNumberTh("Puzzles"),
|
||||
th(attr("data-sort-default") := "1")(trans.clas.nbStudents(students.size)),
|
||||
sortNumberTh(trans.rating()),
|
||||
sortNumberTh(trans.games()),
|
||||
sortNumberTh(trans.puzzles()),
|
||||
th
|
||||
)
|
||||
),
|
||||
|
|
|
@ -27,11 +27,11 @@ object teacherDashboard {
|
|||
a(
|
||||
cls := active.active("progress"),
|
||||
href := routes.Clas.progress(c.id.value, PerfType.Blitz.key, 7)
|
||||
)(
|
||||
"Progress"
|
||||
),
|
||||
a(cls := active.active("edit"), href := routes.Clas.edit(c.id.value))("Edit"),
|
||||
a(cls := active.active("archived"), href := routes.Clas.archived(c.id.value))("Archived")
|
||||
)(trans.clas.progress()),
|
||||
a(cls := active.active("edit"), href := routes.Clas.edit(c.id.value))(trans.edit()),
|
||||
a(cls := active.active("archived"), href := routes.Clas.archived(c.id.value))(
|
||||
trans.clas.removedStudents()
|
||||
)
|
||||
)
|
||||
),
|
||||
standardFlash(),
|
||||
|
@ -39,10 +39,7 @@ object teacherDashboard {
|
|||
div(cls := "clas-show__archived archived")(
|
||||
bits.showArchived(archived),
|
||||
postForm(action := routes.Clas.archive(c.id.value, false))(
|
||||
form3.submit("Restore", icon = none)(
|
||||
cls := "confirm button-empty",
|
||||
title := "Revive the class"
|
||||
)
|
||||
form3.submit(trans.clas.reopen(), icon = none)(cls := "confirm button-empty")
|
||||
)
|
||||
)
|
||||
},
|
||||
|
@ -62,11 +59,11 @@ object teacherDashboard {
|
|||
href := routes.Clas.studentForm(c.id.value),
|
||||
cls := "button button-clas text",
|
||||
dataIcon := "O"
|
||||
)("Add student")
|
||||
)(trans.clas.addStudent())
|
||||
)
|
||||
),
|
||||
if (students.isEmpty)
|
||||
p(cls := "box__pad students__empty")("No students in the class, yet.")
|
||||
p(cls := "box__pad students__empty")(trans.clas.noStudents())
|
||||
else
|
||||
studentList(c, students)
|
||||
)
|
||||
|
@ -78,7 +75,7 @@ object teacherDashboard {
|
|||
layout(c, students.filter(_.student.isActive), "archived") {
|
||||
val archived = students.filter(_.student.isArchived)
|
||||
if (archived.isEmpty)
|
||||
p(cls := "box__pad students__empty")("No archived students.")
|
||||
p(cls := "box__pad students__empty")(trans.clas.noStudents())
|
||||
else
|
||||
studentList(c, archived)
|
||||
}
|
||||
|
@ -91,7 +88,7 @@ object teacherDashboard {
|
|||
layout(c, students, "progress")(
|
||||
div(cls := "progress")(
|
||||
div(cls := "progress-perf")(
|
||||
label("Variant"),
|
||||
label(trans.variant()),
|
||||
div(cls := "progress-choices")(
|
||||
List(
|
||||
PerfType.Bullet,
|
||||
|
@ -109,7 +106,7 @@ object teacherDashboard {
|
|||
)
|
||||
),
|
||||
div(cls := "progress-days")(
|
||||
label("Over days"),
|
||||
label(trans.clas.overDays()),
|
||||
div(cls := "progress-choices")(
|
||||
List(1, 2, 3, 7, 10, 14, 21, 30, 60, 90).map { days =>
|
||||
a(
|
||||
|
@ -125,30 +122,32 @@ object teacherDashboard {
|
|||
thead(
|
||||
tr(
|
||||
th(attr("data-sort-default") := "1")(
|
||||
s"${progress.perfType.name} over last ${progress.days} days"
|
||||
),
|
||||
sortNumberTh("Rating"),
|
||||
sortNumberTh("Progress"),
|
||||
sortNumberTh(if (progress.isPuzzle) "Puzzles" else "Games"),
|
||||
if (progress.isPuzzle) sortNumberTh("Winrate")
|
||||
else sortNumberTh("Time playing")
|
||||
trans.clas.variantXOverLastY(progress.perfType.name, trans.nbDays.txt(progress.days)),
|
||||
sortNumberTh(trans.rating()),
|
||||
sortNumberTh(trans.clas.progress()),
|
||||
sortNumberTh(if (progress.isPuzzle) trans.puzzles() else trans.games()),
|
||||
if (progress.isPuzzle) sortNumberTh(trans.clas.winrate())
|
||||
else sortNumberTh(trans.clas.timePlaying())
|
||||
)
|
||||
),
|
||||
tbody(
|
||||
students.sortBy(_.user.username).map {
|
||||
case s @ Student.WithUser(_, user) =>
|
||||
val prog = progress(user)
|
||||
tr(
|
||||
studentTd(c, s),
|
||||
td(dataSort := user.perfs(progress.perfType).intRating, cls := "rating")(
|
||||
user.perfs(progress.perfType).showRatingProvisional
|
||||
),
|
||||
td(dataSort := prog.ratingProgress)(
|
||||
ratingProgress(prog.ratingProgress) | trans.clas.na.txt()
|
||||
),
|
||||
td(prog.nb),
|
||||
if (progress.isPuzzle) td(dataSort := prog.winRate)(prog.winRate, "%")
|
||||
else td(dataSort := prog.millis)(showPeriod(prog.period))
|
||||
)
|
||||
}
|
||||
)
|
||||
),
|
||||
tbody(
|
||||
students.sortBy(_.user.username).map {
|
||||
case s @ Student.WithUser(_, user) =>
|
||||
val prog = progress(user)
|
||||
tr(
|
||||
studentTd(c, s),
|
||||
td(dataSort := user.perfs(progress.perfType).intRating, cls := "rating")(
|
||||
user.perfs(progress.perfType).showRatingProvisional
|
||||
),
|
||||
td(dataSort := prog.ratingProgress)(ratingProgress(prog.ratingProgress) | "N/A"),
|
||||
td(prog.nb),
|
||||
if (progress.isPuzzle) td(dataSort := prog.winRate)(prog.winRate, "%")
|
||||
else td(dataSort := prog.millis)(showPeriod(prog.period))
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -159,12 +158,12 @@ object teacherDashboard {
|
|||
table(cls := "slist slist-pad sortable")(
|
||||
thead(
|
||||
tr(
|
||||
th(attr("data-sort-default") := "1")("Student"),
|
||||
sortNumberTh("Rating"),
|
||||
sortNumberTh("Games"),
|
||||
sortNumberTh("Puzzles"),
|
||||
sortNumberTh("Active"),
|
||||
th(iconTag("5")(title := "Managed"))
|
||||
th(attr("data-sort-default") := "1")(trans.clas.nbStudents(students.size)),
|
||||
sortNumberTh(trans.rating()),
|
||||
sortNumberTh(trans.games()),
|
||||
sortNumberTh(trans.puzzles()),
|
||||
sortNumberTh(trans.clas.lastActiveDate()),
|
||||
th(iconTag("5")(title := trans.clas.managed.txt()))
|
||||
)
|
||||
),
|
||||
tbody(
|
||||
|
@ -178,7 +177,7 @@ object teacherDashboard {
|
|||
td(user.count.game.localize),
|
||||
td(user.perfs.puzzle.nb),
|
||||
td(dataSort := user.seenAt.map(_.getMillis.toString))(user.seenAt.map(momentFromNowOnce)),
|
||||
td(student.managed option iconTag("5")(title := "Managed"))
|
||||
td(student.managed option iconTag("5")(title := trans.clas.managed.txt()))
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -18,14 +18,14 @@ object wall {
|
|||
teacherDashboard.layout(c, students.filter(_.student.isActive), "wall")(
|
||||
div(cls := "clas-wall__actions")(
|
||||
a(dataIcon := "m", href := routes.Clas.wallEdit(c.id.value), cls := "button button-clas text")(
|
||||
"Edit news"
|
||||
trans.clas.editNews()
|
||||
),
|
||||
a(dataIcon := "e", href := routes.Clas.notifyStudents(c.id.value), cls := "button button-clas text")(
|
||||
"Notify all students"
|
||||
trans.clas.notifyAllStudents()
|
||||
)
|
||||
),
|
||||
if (c.wall.isEmpty)
|
||||
div(cls := "box__pad clas-wall clas-wall--empty")("Nothing here, yet.")
|
||||
div(cls := "box__pad clas-wall clas-wall--empty")(trans.clas.nothingHere())
|
||||
else
|
||||
div(cls := "box__pad clas-wall")(html)
|
||||
)
|
||||
|
@ -38,15 +38,16 @@ object wall {
|
|||
teacherDashboard.layout(c, students, "wall")(
|
||||
div(cls := "box-pad clas-wall__edit")(
|
||||
p(
|
||||
strong("All class news in a single field."),
|
||||
strong(trans.clas.newsEdit1()),
|
||||
ul(
|
||||
li("Add the recent news at the top. Don't delete previous news."),
|
||||
li("Separate news with --- it will display a horizontal line."),
|
||||
li(trans.clas.newsEdit2()),
|
||||
li(trans.clas.newsEdit3()),
|
||||
li(
|
||||
a(href := "https://guides.github.com/features/mastering-markdown/", target := "_blank")(
|
||||
"Markdown"
|
||||
),
|
||||
" is available for more advanced syntax."
|
||||
trans.clas.markdownAvailable(
|
||||
a(href := "https://guides.github.com/features/mastering-markdown/", target := "_blank")(
|
||||
"Markdown"
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
@ -54,7 +55,7 @@ object wall {
|
|||
form3.globalError(form),
|
||||
form3.group(
|
||||
form("wall"),
|
||||
frag("Class news")
|
||||
trans.clas.news()
|
||||
)(form3.textarea(_)(rows := 20)),
|
||||
form3.actions(
|
||||
a(href := routes.Clas.wall(c.id.value))(trans.cancel()),
|
||||
|
|
|
@ -756,6 +756,7 @@ val `agreementNice` = new Translated("agreementNice", Site)
|
|||
val `agreementAccount` = new Translated("agreementAccount", Site)
|
||||
val `agreementPolicy` = new Translated("agreementPolicy", Site)
|
||||
val `searchOrStartNewDiscussion` = new Translated("searchOrStartNewDiscussion", Site)
|
||||
val `edit` = new Translated("edit", Site)
|
||||
val `opponentLeftCounter` = new Translated("opponentLeftCounter", Site)
|
||||
val `mateInXHalfMoves` = new Translated("mateInXHalfMoves", Site)
|
||||
val `nextCaptureOrPawnMoveInXHalfMoves` = new Translated("nextCaptureOrPawnMoveInXHalfMoves", Site)
|
||||
|
@ -1167,6 +1168,73 @@ val `trackStudentProgress` = new Translated("trackStudentProgress", Clas)
|
|||
val `messageAllStudents` = new Translated("messageAllStudents", Clas)
|
||||
val `freeForAllForever` = new Translated("freeForAllForever", Clas)
|
||||
val `applyToBeLichessTeacher` = new Translated("applyToBeLichessTeacher", Clas)
|
||||
val `noClassesYet` = new Translated("noClassesYet", Clas)
|
||||
val `teachersX` = new Translated("teachersX", Clas)
|
||||
val `newClass` = new Translated("newClass", Clas)
|
||||
val `closeClass` = new Translated("closeClass", Clas)
|
||||
val `closedByXAtY` = new Translated("closedByXAtY", Clas)
|
||||
val `reopen` = new Translated("reopen", Clas)
|
||||
val `removeStudent` = new Translated("removeStudent", Clas)
|
||||
val `removedStudents` = new Translated("removedStudents", Clas)
|
||||
val `inviteTheStudentBack` = new Translated("inviteTheStudentBack", Clas)
|
||||
val `sendAMessage` = new Translated("sendAMessage", Clas)
|
||||
val `aLinkToTheClassWillBeAdded` = new Translated("aLinkToTheClassWillBeAdded", Clas)
|
||||
val `className` = new Translated("className", Clas)
|
||||
val `classDescription` = new Translated("classDescription", Clas)
|
||||
val `visibleByBothStudentsAndTeachers` = new Translated("visibleByBothStudentsAndTeachers", Clas)
|
||||
val `teachersOfTheClass` = new Translated("teachersOfTheClass", Clas)
|
||||
val `addLichessUsernames` = new Translated("addLichessUsernames", Clas)
|
||||
val `theyMustFirstApply` = new Translated("theyMustFirstApply", Clas)
|
||||
val `resetPassword` = new Translated("resetPassword", Clas)
|
||||
val `makeSureToCopy` = new Translated("makeSureToCopy", Clas)
|
||||
val `passwordX` = new Translated("passwordX", Clas)
|
||||
val `generateANewPassword` = new Translated("generateANewPassword", Clas)
|
||||
val `invitedToXByY` = new Translated("invitedToXByY", Clas)
|
||||
val `realName` = new Translated("realName", Clas)
|
||||
val `privateWillNeverBeShown` = new Translated("privateWillNeverBeShown", Clas)
|
||||
val `addStudent` = new Translated("addStudent", Clas)
|
||||
val `lichessProfileXCreatedForY` = new Translated("lichessProfileXCreatedForY", Clas)
|
||||
val `studentCredentials` = new Translated("studentCredentials", Clas)
|
||||
val `inviteALichessAccount` = new Translated("inviteALichessAccount", Clas)
|
||||
val `inviteDesc1` = new Translated("inviteDesc1", Clas)
|
||||
val `inviteDesc2` = new Translated("inviteDesc2", Clas)
|
||||
val `inviteDesc3` = new Translated("inviteDesc3", Clas)
|
||||
val `inviteDesc4` = new Translated("inviteDesc4", Clas)
|
||||
val `createANewLichessAccount` = new Translated("createANewLichessAccount", Clas)
|
||||
val `createDesc1` = new Translated("createDesc1", Clas)
|
||||
val `createDesc2` = new Translated("createDesc2", Clas)
|
||||
val `createDesc3` = new Translated("createDesc3", Clas)
|
||||
val `createDesc4` = new Translated("createDesc4", Clas)
|
||||
val `lichessUsername` = new Translated("lichessUsername", Clas)
|
||||
val `generateANewUsername` = new Translated("generateANewUsername", Clas)
|
||||
val `onlyVisibleToTeachers` = new Translated("onlyVisibleToTeachers", Clas)
|
||||
val `lastActiveDate` = new Translated("lastActiveDate", Clas)
|
||||
val `managed` = new Translated("managed", Clas)
|
||||
val `thisStudentAccountIsManaged` = new Translated("thisStudentAccountIsManaged", Clas)
|
||||
val `upgradeFromManaged` = new Translated("upgradeFromManaged", Clas)
|
||||
val `release` = new Translated("release", Clas)
|
||||
val `releaseTheAccount` = new Translated("releaseTheAccount", Clas)
|
||||
val `releaseDesc1` = new Translated("releaseDesc1", Clas)
|
||||
val `releaseDesc2` = new Translated("releaseDesc2", Clas)
|
||||
val `realUniqueEmail` = new Translated("realUniqueEmail", Clas)
|
||||
val `teachers` = new Translated("teachers", Clas)
|
||||
val `progress` = new Translated("progress", Clas)
|
||||
val `noStudents` = new Translated("noStudents", Clas)
|
||||
val `overDays` = new Translated("overDays", Clas)
|
||||
val `timePlaying` = new Translated("timePlaying", Clas)
|
||||
val `variantXOverLastY` = new Translated("variantXOverLastY", Clas)
|
||||
val `winrate` = new Translated("winrate", Clas)
|
||||
val `na` = new Translated("na", Clas)
|
||||
val `news` = new Translated("news", Clas)
|
||||
val `editNews` = new Translated("editNews", Clas)
|
||||
val `notifyAllStudents` = new Translated("notifyAllStudents", Clas)
|
||||
val `nothingHere` = new Translated("nothingHere", Clas)
|
||||
val `newsEdit1` = new Translated("newsEdit1", Clas)
|
||||
val `newsEdit2` = new Translated("newsEdit2", Clas)
|
||||
val `newsEdit3` = new Translated("newsEdit3", Clas)
|
||||
val `markdownAvailable` = new Translated("markdownAvailable", Clas)
|
||||
val `nbTeachers` = new Translated("nbTeachers", Clas)
|
||||
val `nbStudents` = new Translated("nbStudents", Clas)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,4 +8,81 @@
|
|||
<string name="messageAllStudents">Message all students about new class material</string>
|
||||
<string name="freeForAllForever">100% free for all, forever, with no ads or trackers</string>
|
||||
<string name="applyToBeLichessTeacher">Apply to be a Lichess Teacher</string>
|
||||
<string name="noClassesYet">No classes yet.</string>
|
||||
<string name="teachersX">Teachers: %s</string>
|
||||
<string name="newClass">New class</string>
|
||||
<string name="closeClass">Close class</string>
|
||||
<string name="closedByXAtY">Closed by %1$s %2$s</string>
|
||||
<string name="reopen">Reopen</string>
|
||||
<string name="removeStudent">Remove student</string>
|
||||
<string name="removedStudents">Removed</string>
|
||||
<string name="inviteTheStudentBack">Invite the student back</string>
|
||||
<string name="sendAMessage">Send a message to all students.</string>
|
||||
<string name="aLinkToTheClassWillBeAdded">A link to the class will be automatically added at the end of the message, so you don't need to include it yourself.</string>
|
||||
<string name="className">Class name</string>
|
||||
<string name="classDescription">Class description</string>
|
||||
<string name="visibleByBothStudentsAndTeachers">Visible by both teachers and students of the class</string>
|
||||
<string name="teachersOfTheClass">Teachers of the class</string>
|
||||
<string name="addLichessUsernames">Add Lichess usernames to invite them as teachers. One per line.</string>
|
||||
<string name="theyMustFirstApply">They must first apply to be Lichess Teachers.</string>
|
||||
<string name="resetPassword">Reset password</string>
|
||||
<string name="makeSureToCopy">Make sure to copy or write down the password now. You won’t be able to see it again!</string>
|
||||
<string name="passwordX">Password: %s</string>
|
||||
<string name="generateANewPassword">Generate a new password for the student</string>
|
||||
<string name="invitedToXByY">Invited to %1$s by %2$s</string>
|
||||
<string name="realName">Real name</string>
|
||||
<string name="privateWillNeverBeShown">Private. Will never be shown outside the class. Helps remember who the student is.</string>
|
||||
<string name="addStudent">Add student</string>
|
||||
<string name="lichessProfileXCreatedForY">Lichess profile %1$s created for %2$s.</string>
|
||||
<string name="studentCredentials">
|
||||
Student: %1$s
|
||||
Username: %2$s
|
||||
Password: %2$s
|
||||
</string>
|
||||
<string name="inviteALichessAccount">Invite a Lichess account</string>
|
||||
<string name="inviteDesc1">If the student already has a Lichess account, you can invite them to the class.</string>
|
||||
<string name="inviteDesc2">They will receive a message on Lichess with a link to join the class.</string>
|
||||
<string name="inviteDesc3">Important: only invite students you know, and who actively want to join the class.</string>
|
||||
<string name="inviteDesc4">Never send unsolicited invites to arbitrary players.</string>
|
||||
<string name="createANewLichessAccount">Create a new Lichess account</string>
|
||||
<string name="createDesc1">If the student doesn't have a Lichess account yet, you can create one for them here.</string>
|
||||
<string name="createDesc2">No email address is required. A password will be generated, and you will have to transmit it to the student, so they can log in.</string>
|
||||
<string name="createDesc3">Important: a student must not have multiple accounts.</string>
|
||||
<string name="createDesc4">If they already have one, use the invite form instead.</string>
|
||||
<string name="lichessUsername">Lichess username</string>
|
||||
<string name="generateANewUsername">Generate a new username</string>
|
||||
<string name="onlyVisibleToTeachers">Only visible to the class teachers</string>
|
||||
<string name="lastActiveDate">Active</string>
|
||||
<string name="managed">Managed</string>
|
||||
<string name="thisStudentAccountIsManaged">This student account is managed</string>
|
||||
<string name="upgradeFromManaged">Upgrade from managed to autonomous</string>
|
||||
<string name="release">Release</string>
|
||||
<string name="releaseTheAccount">Release the account so the student can manage it in autonomy.</string>
|
||||
<string name="releaseDesc1">A released account cannot be made managed again. The student will be able to toggle kid mode and reset paswword themselves.</string>
|
||||
<string name="releaseDesc2">The student will remain in the class after their account is released.</string>
|
||||
<string name="realUniqueEmail">Real, unique email address of the student. We will send a confirmation email to it, with a link to release the account.</string>
|
||||
<string name="teachers">Teachers</string>
|
||||
<plurals name="nbTeachers">
|
||||
<item quantity="one">Teacher</item>
|
||||
<item quantity="other">%s teachers</item>
|
||||
</plurals>
|
||||
<plurals name="nbStudents">
|
||||
<item quantity="one">Student</item>
|
||||
<item quantity="other">%s students</item>
|
||||
</plurals>
|
||||
<string name="progress">Progress</string>
|
||||
<string name="noStudents">No students in the class, yet.</string>
|
||||
<string name="overDays">"Over days"</string>
|
||||
<string name="timePlaying">Time playing</string>
|
||||
<string name="variantXOverLastY">%1$s over last %2$s</string>
|
||||
<string name="winrate">Winrate</string>
|
||||
<string name="na">N/A</string>
|
||||
<string name="news">Class news</string>
|
||||
<string name="editNews">Edit news</string>
|
||||
<string name="notifyAllStudents">Notify all students</string>
|
||||
<string name="nothingHere">Nothing here, yet.</string>
|
||||
<string name="newsEdit1">All class news in a single field.</string>
|
||||
<string name="newsEdit2">Add the recent news at the top. Don't delete previous news.</string>
|
||||
<string name="newsEdit3">Separate news with --- it will display a horizontal line.</string>
|
||||
<string name="markdownAvailable">%s is available for more advanced syntax.</string>
|
||||
</resources>
|
||||
|
|
|
@ -901,4 +901,5 @@ computer analysis, game chat and shareable URL.</string>
|
|||
<string name="agreementAccount">I agree that I will not create multiple accounts.</string>
|
||||
<string name="agreementPolicy">I agree that I will follow all Lichess policies.</string>
|
||||
<string name="searchOrStartNewDiscussion">Search or start new discussion</string>
|
||||
<string name="edit">Edit</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue