diff --git a/app/views/base/topnav.scala b/app/views/base/topnav.scala
index ad008801a0..9bf690413a 100644
--- a/app/views/base/topnav.scala
+++ b/app/views/base/topnav.scala
@@ -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(
diff --git a/app/views/clas/bits.scala b/app/views/clas/bits.scala
index 39f4058389..91d5af34c7 100644
--- a/app/views/clas/bits.scala
+++ b/app/views/clas/bits.scala
@@ -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")
diff --git a/app/views/clas/clas.scala b/app/views/clas/clas.scala
index d49c959271..ad6f919dce 100644
--- a/app/views/clas/clas.scala
+++ b/app/views/clas/clas.scala
@@ -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))
},
diff --git a/app/views/clas/student.scala b/app/views/clas/student.scala
index bef5431c7b..90848faf8d 100644
--- a/app/views/clas/student.scala
+++ b/app/views/clas/student.scala
@@ -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()),
diff --git a/app/views/clas/studentDashboard.scala b/app/views/clas/studentDashboard.scala
index eb6c3240c6..bbc6afc484 100644
--- a/app/views/clas/studentDashboard.scala
+++ b/app/views/clas/studentDashboard.scala
@@ -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
)
),
diff --git a/app/views/clas/teacherDashboard.scala b/app/views/clas/teacherDashboard.scala
index 472805d995..76044157c6 100644
--- a/app/views/clas/teacherDashboard.scala
+++ b/app/views/clas/teacherDashboard.scala
@@ -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()))
)
}
)
diff --git a/app/views/clas/wall.scala b/app/views/clas/wall.scala
index 12be1f6f23..3764ae22e6 100644
--- a/app/views/clas/wall.scala
+++ b/app/views/clas/wall.scala
@@ -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()),
diff --git a/modules/i18n/src/main/I18nKeys.scala b/modules/i18n/src/main/I18nKeys.scala
index 0fcddd5278..b96497ccda 100644
--- a/modules/i18n/src/main/I18nKeys.scala
+++ b/modules/i18n/src/main/I18nKeys.scala
@@ -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)
}
}
diff --git a/translation/source/class.xml b/translation/source/class.xml
index b6ab437541..88c45497a0 100644
--- a/translation/source/class.xml
+++ b/translation/source/class.xml
@@ -8,4 +8,81 @@
Message all students about new class material
100% free for all, forever, with no ads or trackers
Apply to be a Lichess Teacher
+ No classes yet.
+ Teachers: %s
+ New class
+ Close class
+ Closed by %1$s %2$s
+ Reopen
+ Remove student
+ Removed
+ Invite the student back
+ Send a message to all students.
+ A link to the class will be automatically added at the end of the message, so you don't need to include it yourself.
+ Class name
+ Class description
+ Visible by both teachers and students of the class
+ Teachers of the class
+ Add Lichess usernames to invite them as teachers. One per line.
+ They must first apply to be Lichess Teachers.
+ Reset password
+ Make sure to copy or write down the password now. You won’t be able to see it again!
+ Password: %s
+ Generate a new password for the student
+ Invited to %1$s by %2$s
+ Real name
+ Private. Will never be shown outside the class. Helps remember who the student is.
+ Add student
+ Lichess profile %1$s created for %2$s.
+
+Student: %1$s
+Username: %2$s
+Password: %2$s
+
+ Invite a Lichess account
+ If the student already has a Lichess account, you can invite them to the class.
+ They will receive a message on Lichess with a link to join the class.
+ Important: only invite students you know, and who actively want to join the class.
+ Never send unsolicited invites to arbitrary players.
+ Create a new Lichess account
+ If the student doesn't have a Lichess account yet, you can create one for them here.
+ 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.
+ Important: a student must not have multiple accounts.
+ If they already have one, use the invite form instead.
+ Lichess username
+ Generate a new username
+ Only visible to the class teachers
+ Active
+ Managed
+ This student account is managed
+ Upgrade from managed to autonomous
+ Release
+ Release the account so the student can manage it in autonomy.
+ A released account cannot be made managed again. The student will be able to toggle kid mode and reset paswword themselves.
+ The student will remain in the class after their account is released.
+ Real, unique email address of the student. We will send a confirmation email to it, with a link to release the account.
+ Teachers
+
+ - Teacher
+ - %s teachers
+
+
+ - Student
+ - %s students
+
+ Progress
+ No students in the class, yet.
+ "Over days"
+ Time playing
+ %1$s over last %2$s
+ Winrate
+ N/A
+ Class news
+ Edit news
+ Notify all students
+ Nothing here, yet.
+ All class news in a single field.
+ Add the recent news at the top. Don't delete previous news.
+ Separate news with --- it will display a horizontal line.
+ %s is available for more advanced syntax.
diff --git a/translation/source/site.xml b/translation/source/site.xml
index 01be9fc1b3..767e2f6a5b 100644
--- a/translation/source/site.xml
+++ b/translation/source/site.xml
@@ -901,4 +901,5 @@ computer analysis, game chat and shareable URL.
I agree that I will not create multiple accounts.
I agree that I will follow all Lichess policies.
Search or start new discussion
+ Edit