class design
parent
16e6d86ed1
commit
1f7d91b653
|
@ -113,7 +113,9 @@ final class Clas(
|
|||
|
||||
def edit(id: String) = Secure(_.Teacher) { implicit ctx => me =>
|
||||
WithClass(me, id) { _ => clas =>
|
||||
Ok(html.clas.clas.edit(clas, env.clas.forms.edit(clas))).fuccess
|
||||
env.clas.api.student.activeWithUsers(clas) map { students =>
|
||||
Ok(html.clas.clas.edit(clas, students, env.clas.forms.edit(clas)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,7 +125,10 @@ final class Clas(
|
|||
.edit(clas)
|
||||
.bindFromRequest()(ctx.body)
|
||||
.fold(
|
||||
err => BadRequest(html.clas.clas.edit(clas, err)).fuccess,
|
||||
err =>
|
||||
env.clas.api.student.activeWithUsers(clas) map { students =>
|
||||
BadRequest(html.clas.clas.edit(clas, students, err))
|
||||
},
|
||||
data =>
|
||||
env.clas.api.clas.update(clas, data) map { clas =>
|
||||
Redirect(routes.Clas.show(clas.id.value)).flashSuccess
|
||||
|
|
|
@ -5,7 +5,7 @@ import play.api.data.Form
|
|||
import lila.api.Context
|
||||
import lila.app.templating.Environment._
|
||||
import lila.app.ui.ScalatagsTemplate._
|
||||
import lila.clas.Clas
|
||||
import lila.clas.{ Clas, Student }
|
||||
import lila.clas.ClasForm.ClasData
|
||||
import controllers.routes
|
||||
|
||||
|
@ -39,7 +39,7 @@ object clas {
|
|||
h1("Lichess Classes"),
|
||||
a(
|
||||
href := routes.Clas.form,
|
||||
cls := "new button button-green button-empty",
|
||||
cls := "new button button-empty",
|
||||
title := "New Class",
|
||||
dataIcon := "O"
|
||||
)
|
||||
|
@ -86,19 +86,19 @@ object clas {
|
|||
innerForm(form, none)
|
||||
)
|
||||
|
||||
def edit(c: lila.clas.Clas, form: Form[ClasData])(implicit ctx: Context) =
|
||||
bits.layout(c.name, Left(c withStudents Nil))(
|
||||
cls := "box-pad",
|
||||
h1("Edit ", c.name),
|
||||
innerForm(form, c.some),
|
||||
hr,
|
||||
c.isActive option postForm(
|
||||
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"
|
||||
def edit(c: lila.clas.Clas, students: List[Student.WithUser], form: Form[ClasData])(implicit ctx: Context) =
|
||||
teacherDashboard.layout(c, students, "edit")(
|
||||
div(cls := "box-pad")(
|
||||
innerForm(form, c.some),
|
||||
hr,
|
||||
c.isActive option postForm(
|
||||
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"
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -10,48 +10,48 @@ import lila.common.String.html.richText
|
|||
|
||||
object teacherDashboard {
|
||||
|
||||
private def dashboard(
|
||||
private[clas] def layout(
|
||||
c: Clas,
|
||||
students: List[Student.WithUser],
|
||||
active: String
|
||||
)(modifiers: Modifier*)(implicit ctx: Context) =
|
||||
bits.layout(c.name, Left(c withStudents students.map(_.student)))(
|
||||
cls := "clas-show dashboard dashboard-teacher",
|
||||
div(cls := "box__top")(
|
||||
h1(dataIcon := "f", cls := "text")(c.name),
|
||||
div(cls := "box__top__actions")(
|
||||
cls := s"clas-show dashboard dashboard-teacher dashboard-teacher-$active",
|
||||
div(cls := "clas-show__top")(
|
||||
div(cls := "box__top")(
|
||||
h1(dataIcon := "f", cls := "text")(c.name),
|
||||
div(cls := "box__top__actions")(
|
||||
a(
|
||||
href := routes.Clas.studentForm(c.id.value),
|
||||
cls := "button button-green text",
|
||||
dataIcon := "O"
|
||||
)("Add student")
|
||||
)
|
||||
),
|
||||
st.nav(cls := "dashboard-nav")(
|
||||
a(cls := active.active("overview"), href := routes.Clas.show(c.id.value))("Overview"),
|
||||
a(
|
||||
href := routes.Clas.edit(c.id.value),
|
||||
cls := "button button-empty"
|
||||
)("Edit"),
|
||||
a(
|
||||
href := routes.Clas.studentForm(c.id.value),
|
||||
cls := "button button-green text",
|
||||
dataIcon := "O"
|
||||
)("Add student")
|
||||
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")
|
||||
)
|
||||
),
|
||||
div(cls := "box__pad")(
|
||||
standardFlash(),
|
||||
c.archived map { archived =>
|
||||
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"
|
||||
)
|
||||
standardFlash(),
|
||||
c.archived map { archived =>
|
||||
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"
|
||||
)
|
||||
)
|
||||
}
|
||||
),
|
||||
st.nav(cls := "dashboard-nav tabs-horiz")(
|
||||
a(cls := active.active("overview"), href := routes.Clas.show(c.id.value))("Overview"),
|
||||
a(cls := active.active("progress"), href := routes.Clas.progress(c.id.value, PerfType.Blitz.key, 7))(
|
||||
"Progress"
|
||||
),
|
||||
a(cls := active.active("archived"), href := routes.Clas.archived(c.id.value))("Archived")
|
||||
),
|
||||
)
|
||||
},
|
||||
modifiers
|
||||
)
|
||||
|
||||
|
@ -59,7 +59,7 @@ object teacherDashboard {
|
|||
c: Clas,
|
||||
students: List[Student.WithUser]
|
||||
)(implicit ctx: Context) =
|
||||
dashboard(c, students, "overview")(
|
||||
layout(c, students, "overview")(
|
||||
div(cls := "clas-show__overview")(
|
||||
c.desc.trim.nonEmpty option div(cls := "clas-desc")(richText(c.desc)),
|
||||
clas.teachers(c)
|
||||
|
@ -74,7 +74,7 @@ object teacherDashboard {
|
|||
c: Clas,
|
||||
students: List[Student.WithUser]
|
||||
)(implicit ctx: Context) =
|
||||
dashboard(c, students.filter(_.student.isActive), "archived") {
|
||||
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.")
|
||||
|
@ -87,7 +87,7 @@ object teacherDashboard {
|
|||
students: List[Student.WithUser],
|
||||
progress: ClasProgress
|
||||
)(implicit ctx: Context) =
|
||||
dashboard(c, students, "progress")(
|
||||
layout(c, students, "progress")(
|
||||
div(cls := "progress")(
|
||||
div(cls := "progress-perf")(
|
||||
label("Variant"),
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
%box-radius-bottom {
|
||||
border-radius: 0 0 $box-radius-size $box-radius-size;
|
||||
}
|
||||
%box-radius-top-left {
|
||||
border-radius: $box-radius-size 0 0 0;
|
||||
}
|
||||
%box-radius-top-right {
|
||||
border-radius: 0 $box-radius-size 0 0;
|
||||
}
|
||||
%box-shadow {
|
||||
@include box-shadow;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
$c-tabs-active: $c-accent !default;
|
||||
|
||||
.tabs-horiz {
|
||||
@extend %flex-center-nowrap, %page-text;
|
||||
justify-content: center;
|
||||
|
@ -6,7 +8,7 @@
|
|||
@include breakpoint($mq-not-xx-small) {
|
||||
font-size: .9em;
|
||||
}
|
||||
span, > a {
|
||||
span {
|
||||
@extend %roboto;
|
||||
flex: 1 1 auto;
|
||||
text-align: center;
|
||||
|
@ -21,7 +23,7 @@
|
|||
}
|
||||
&::after {
|
||||
content: '';
|
||||
background: fade-out($c-accent, .3);
|
||||
background: fade-out($c-tabs-active, .3);
|
||||
height: 2px;
|
||||
position: absolute;
|
||||
width: 96%;
|
||||
|
@ -37,7 +39,7 @@
|
|||
}
|
||||
}
|
||||
&.active {
|
||||
color: $c-accent;
|
||||
color: $c-tabs-active;
|
||||
}
|
||||
}
|
||||
.unread {
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
$clas-color: rgb(127, 90, 240);
|
||||
$c-clas: rgb(127, 90, 240);
|
||||
|
||||
$c-font-clas: mix($c-font-clear, $c-clas, 30%);
|
||||
$c-bg-clas: $c-clas;
|
||||
$c-bg-clas-over: white;
|
||||
$c-bg-clas-over-dim: mix($c-bg-clas-over, $c-bg-clas, 80%);
|
||||
|
||||
%archived {
|
||||
@extend %box-radius, %flex-between;
|
||||
|
@ -13,6 +18,12 @@ $clas-color: rgb(127, 90, 240);
|
|||
@include breakpoint($mq-medium) {
|
||||
max-width: 15vw;
|
||||
}
|
||||
&.active {
|
||||
color: $c-font-clas;
|
||||
}
|
||||
&::after {
|
||||
background: $c-clas;
|
||||
}
|
||||
&.student {
|
||||
em {
|
||||
@extend %roboto;
|
||||
|
@ -21,12 +32,6 @@ $clas-color: rgb(127, 90, 240);
|
|||
@include breakpoint($mq-subnav-side) {
|
||||
font-weight: bold;
|
||||
padding: .4rem 2vw .4rem .8rem;
|
||||
&.active {
|
||||
color: $clas-color;
|
||||
}
|
||||
&::after {
|
||||
background: $clas-color;
|
||||
}
|
||||
em {
|
||||
font-weight: normal;
|
||||
display: block;
|
||||
|
@ -37,7 +42,12 @@ $clas-color: rgb(127, 90, 240);
|
|||
|
||||
.clas-index {
|
||||
.box__top {
|
||||
background: $c-bg-clas;
|
||||
&, a {
|
||||
color: $c-bg-clas-over;
|
||||
}
|
||||
flex-flow: row nowrap;
|
||||
h1 { margin: 0 }
|
||||
}
|
||||
.new::before {
|
||||
font-size: 3em;
|
||||
|
@ -53,7 +63,7 @@ $clas-color: rgb(127, 90, 240);
|
|||
position: relative;
|
||||
@include transition();
|
||||
&::before {
|
||||
color: mix($c-link, $c-bg-box, 80%);
|
||||
color: mix($c-clas, $c-bg-box, 80%);
|
||||
font-size: 5em;
|
||||
margin-right: .4em;
|
||||
@include transition();
|
||||
|
@ -62,9 +72,9 @@ $clas-color: rgb(127, 90, 240);
|
|||
}
|
||||
}
|
||||
&:hover {
|
||||
background: mix($c-link, $c-bg-box, 10%);
|
||||
background: mix($c-clas, $c-bg-box, 10%);
|
||||
&::before {
|
||||
color: mix($c-link, $c-bg-box, 100%);
|
||||
color: mix($c-clas, $c-bg-box, 100%);
|
||||
}
|
||||
}
|
||||
.overlay {
|
||||
|
@ -72,7 +82,7 @@ $clas-color: rgb(127, 90, 240);
|
|||
}
|
||||
h3 {
|
||||
@include fluid-size('font-size', 23px, 35px);
|
||||
color: $c-link;
|
||||
color: $c-clas;
|
||||
}
|
||||
p {
|
||||
margin: .5em 0 0 0;
|
||||
|
@ -88,6 +98,13 @@ $clas-color: rgb(127, 90, 240);
|
|||
|
||||
.clas-show {
|
||||
|
||||
&__top {
|
||||
background: $c-bg-clas;
|
||||
&, a, .button, .title {
|
||||
color: $c-bg-clas-over;
|
||||
}
|
||||
}
|
||||
|
||||
&__overview {
|
||||
@extend %box-padding;
|
||||
background: $c-bg-zebra;
|
||||
|
@ -100,12 +117,11 @@ $clas-color: rgb(127, 90, 240);
|
|||
|
||||
.dashboard {
|
||||
|
||||
.tabs-horiz a {
|
||||
letter-spacing: normal;
|
||||
font-size: 1.1em;
|
||||
color: $c-font;
|
||||
&.active {
|
||||
color: $c-accent;
|
||||
.flash {
|
||||
margin: 0;
|
||||
&__content {
|
||||
padding: 2em var(--box-padding);
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,6 +157,39 @@ $clas-color: rgb(127, 90, 240);
|
|||
}
|
||||
}
|
||||
|
||||
&-nav {
|
||||
@extend %flex-center-nowrap;
|
||||
justify-content: center;
|
||||
align-items: flex-end;
|
||||
@include breakpoint($mq-not-xx-small) {
|
||||
font-size: .9em;
|
||||
}
|
||||
a {
|
||||
@extend %box-radius-top;
|
||||
flex: 1 1 auto;
|
||||
text-align: center;
|
||||
padding: 1.2em 0 .8em 0;
|
||||
&:first-child {
|
||||
@extend %box-radius-top-right;
|
||||
}
|
||||
&:last-child {
|
||||
@extend %box-radius-top-left;
|
||||
}
|
||||
&:hover {
|
||||
background: mix($c-bg-zebra, $c-clas, 20%);
|
||||
}
|
||||
&.active {
|
||||
background: $c-bg-zebra;
|
||||
color: $c-font-clas;
|
||||
font-weight: bold;
|
||||
.dashboard-teacher-edit &,
|
||||
.dashboard-teacher-archived & {
|
||||
background: $c-bg-box;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-student {
|
||||
.teachers {
|
||||
margin-bottom: 2em;
|
||||
|
@ -170,6 +219,9 @@ $clas-color: rgb(127, 90, 240);
|
|||
}
|
||||
&-choices {
|
||||
@extend %flex-center, %box-neat-force;
|
||||
@if $theme-dark {
|
||||
box-shadow: none;
|
||||
}
|
||||
flex: 1 1 auto;
|
||||
background: $c-bg-box;
|
||||
}
|
||||
|
@ -178,13 +230,13 @@ $clas-color: rgb(127, 90, 240);
|
|||
text-align: center;
|
||||
font-weight: bold;
|
||||
padding: .7em;
|
||||
color: $c-good;
|
||||
color: $c-clas;
|
||||
&:hover {
|
||||
background: mix($c-bg-box, $c-good, 70%);
|
||||
background: mix($c-bg-box, $c-clas, 70%);
|
||||
color: $c-font-clear;
|
||||
}
|
||||
&.active {
|
||||
background: $c-good;
|
||||
background: $c-clas;
|
||||
color: $c-good-over;
|
||||
}
|
||||
border-right: 1px solid $c-border;
|
||||
|
@ -213,22 +265,18 @@ $clas-color: rgb(127, 90, 240);
|
|||
|
||||
.student-show {
|
||||
|
||||
$top-background: $clas-color;
|
||||
$top-font: white;
|
||||
$top-font-dim: mix($top-font, $top-background, 80%);
|
||||
|
||||
padding-bottom: 3em;
|
||||
|
||||
&__top {
|
||||
padding: calc(5vh - 1rem) var(--box-padding);
|
||||
background: $top-background;
|
||||
background: $c-bg-clas;
|
||||
margin-bottom: 3em;
|
||||
&, a, .button, .title {
|
||||
color: $top-font;
|
||||
color: $c-bg-clas-over;
|
||||
}
|
||||
a:not(.button) {
|
||||
font-weight: bold;
|
||||
border-bottom: 1px dotted $top-font-dim;
|
||||
border-bottom: 1px dotted $c-bg-clas-over-dim;
|
||||
}
|
||||
h1 {
|
||||
@extend %flex-center;
|
||||
|
@ -236,14 +284,14 @@ $clas-color: rgb(127, 90, 240);
|
|||
&::before {
|
||||
font-size: 2.5em;
|
||||
margin-right: .4em;
|
||||
color: $top-font-dim;
|
||||
color: $c-bg-clas-over-dim;
|
||||
}
|
||||
strong {
|
||||
display: block;
|
||||
}
|
||||
em {
|
||||
@extend %roboto;
|
||||
color: $top-font-dim;
|
||||
color: $c-bg-clas-over-dim;
|
||||
}
|
||||
}
|
||||
&__meta {
|
||||
|
|
|
@ -2,6 +2,5 @@
|
|||
@import '../../../common/css/form/form3';
|
||||
@import '../../../common/css/component/slist';
|
||||
@import '../../../common/css/component/tablesort';
|
||||
@import '../../../common/css/component/tabs-horiz';
|
||||
@import '../user/activity';
|
||||
@import '../clas';
|
||||
|
|
Loading…
Reference in New Issue