Add dark mode

This commit is contained in:
Lars Westermann 2019-05-31 22:51:22 +02:00
parent df8f04099a
commit f90a4dddba
Signed by: lars.westermann
GPG key ID: 9D417FA5BB9D5E1D
12 changed files with 296 additions and 133 deletions

View file

@ -0,0 +1,39 @@
$background-primary-color: #fff;
$background-secondary-color: #fcfcfc;
$text-primary-color: #333;
$text-secondary-color: rgba($text-primary-color, 0.5);
$primary-color: #B11D33;
$primary-text-color: #fff;
$error-color: #F00;
$error-text-color: #fff;
$input-border-color: #888;
$table-border-color: rgba($text-primary-color, 0.1);
$table-header-color: rgba($text-primary-color, 0.06);
$shadow-color: rgba($text-primary-color, 0.8);
$bg-disabled-color: rgba($text-primary-color, .26);
$bg-enabled-color: rgba($primary-color, .5);
$lever-disabled-color: $background-primary-color;
$lever-enabled-color: $primary-color;
$error-background-color: rgba($error-color, 0.5);
@mixin color-setting {
:root {
--background-primary-color: $background-primary-color;
--background-secondary-color: $background-secondary-color;
--text-primary-color: $text-primary-color;
--text-secondary-color: $text-secondary-color;
--primary-color: $primary-color;
--primary-text-color: $primary-text-color;
--error-color: $error-color;
--error-text-color: $error-text-color;
--input-border-color: $input-border-color;
--table-border-color: $table-border-color;
--table-header-color: $table-header-color;
--shadow-color: $shadow-color;
--bg-disabled-color: $bg-disabled-color;
--bg-enabled-color: $bg-enabled-color;
--lever-disabled-color: $lever-disabled-color;
--lever-enabled-color: $lever-enabled-color;
--error-background-color: $error-background-color;
}
}

View file

@ -0,0 +1,21 @@
@import "_color.scss";
$background-primary-color: #2d2d2d;
$background-secondary-color: #373737;
$text-primary-color: #fff;
$text-secondary-color: rgba($text-primary-color, 0.5);
$primary-color: #dd213d;
$primary-text-color: #fff;
$error-color: #F00;
$error-text-color: #fff;
$input-border-color: #888;
$table-border-color: rgba($text-primary-color, 0.1);
$table-header-color: rgba($text-primary-color, 0.06);
$shadow-color: rgba($text-primary-color, 0.8);
$bg-disabled-color: rgba($text-primary-color, .26);
$bg-enabled-color: rgba($primary-color, .5);
$lever-disabled-color: $background-primary-color;
$lever-enabled-color: $primary-color;
$error-background-color: rgba($error-color, 0.5);
@include color-setting;

View file

@ -1,3 +1,5 @@
@import "_color.scss";
@mixin no-select() {
-webkit-touch-callout: none;
-webkit-user-select: none;
@ -7,35 +9,14 @@
user-select: none;
}
$background-primary-color: #fff;
$background-secondary-color: #fcfcfc;
$text-primary-color: #333;
$text-secondary-color: rgba($text-primary-color, 0.5);
$primary-color: #B11D33;
$primary-text-color: #fff;
$error-color: #D55225;
$error-text-color: #fff;
$input-border-color: #888;
$table-border-color: rgba($text-primary-color, 0.1);
$table-header-color: rgba($text-primary-color, 0.06);
$border-radius: 0.2rem;
$transitionTime: 150ms;
$bg-disabled-color: rgba($text-primary-color, .26);
$bg-enabled-color: rgba($primary-color, .5);
$lever-disabled-color: $background-primary-color;
$lever-enabled-color: $primary-color;
$error-background-color: #FFCDD2;
@include color-setting;
body, html {
color: $text-primary-color;
background: $background-secondary-color;
color: var(--text-primary-color);
background: var(--background-secondary-color);
font-family: 'Montserrat', Roboto, Arial, sans-serif;
font-weight: 600;
@ -57,14 +38,14 @@ body, html {
a {
text-decoration: none;
outline: none;
color: $primary-color;
color: var(--primary-color);
&:hover {
text-decoration: none;
}
&:active {
color: $primary-color;
color: var(--primary-color);
}
}
@ -98,8 +79,8 @@ a {
}
.menu {
background-color: $background-secondary-color;
color: $text-primary-color;
background-color: var(--background-secondary-color);
color: var(--text-primary-color);
width: 100%;
clear: both;
height: 6rem;
@ -107,7 +88,7 @@ a {
a {
padding: 0 1rem;
color: $text-primary-color;
color: var(--text-primary-color);
height: 100%;
display: inline-block;
font-family: "Bungee", sans-serif;
@ -132,14 +113,14 @@ a {
}
&.active::after {
background: $text-primary-color;
background: var(--text-primary-color);
}
&:hover {
background-color: $table-border-color;
background-color: var(--table-border-color);
&::after {
background: $primary-color;
background: var(--primary-color);
}
}
}
@ -162,7 +143,7 @@ a {
cursor: default;
padding: 0 1rem;
color: $text-primary-color;
color: var(--text-primary-color);
height: 100%;
font-size: 2rem;
position: relative;
@ -171,7 +152,7 @@ a {
.menu-content {
display: none;
position: absolute;
background-color: $background-secondary-color;
background-color: var(--background-secondary-color);
z-index: 5;
left: 0;
right: 0;
@ -264,14 +245,10 @@ a {
}
tr {
border-top: solid 1px $table-border-color;
&:nth-child(odd) {
//background-color: rgba($text-primary-color, 0.01);
}
border-top: solid 1px var(--table-border-color);
&:first-child {
background-color: $table-header-color;
background-color: var(--table-header-color);
height: 2.5rem;
line-height: 2.5rem;
}
@ -281,7 +258,7 @@ a {
line-height: 2rem;
&:hover {
background-color: $table-header-color;
background-color: var(--table-header-color);
}
}
}
@ -295,16 +272,16 @@ a {
}
&.error {
background-color: $error-background-color;
background-color: var(--error-background-color);
}
}
.table-select-box {
position: absolute;
z-index: 1;
background: $background-primary-color;
background: var(--background-primary-color);
width: 10rem;
border: solid 1px $input-border-color;
border: solid 1px var(--input-border-color);
border-radius: $border-radius;
padding: 0.5rem 0;
@ -312,26 +289,27 @@ a {
padding: 0 0.5rem;
&:hover {
background-color: $table-header-color;
background-color: var(--table-header-color);
}
}
}
}
.form-control {
border: solid 1px $input-border-color;
border: solid 1px var(--input-border-color);
outline: none;
padding: 0 1rem;
line-height: 2.5rem;
height: 2.5rem;
width: 100%;
background-color: $background-primary-color;
background-color: var(--background-primary-color);
border-radius: $border-radius;
margin: 1px;
transition: border-color $transitionTime;
color: var(--text-primary-color);
&:focus {
border-color: $primary-color;
border-color: var(--primary-color);
border-width: 2px;
}
}
@ -344,7 +322,7 @@ textarea.form-control {
select:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 $text-primary-color;
text-shadow: 0 0 0 var(--text-primary-color);
}
.form-group {
@ -385,7 +363,7 @@ select:-moz-focusring {
left: 0;
width: 36px;
height: 14px;
background-color: $bg-disabled-color;
background-color: var(--bg-disabled-color);
border-radius: 14px;
z-index: 1;
transition: background-color 0.28s cubic-bezier(.4, 0, .2, 1);
@ -398,7 +376,7 @@ select:-moz-focusring {
left: 0;
width: 20px;
height: 20px;
background-color: $lever-disabled-color;
background-color: var(--lever-disabled-color);
border-radius: 14px;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
z-index: 2;
@ -411,12 +389,12 @@ select:-moz-focusring {
input:checked + label {
&:before {
background-color: $bg-enabled-color;
background-color: var(--bg-enabled-color);
}
&:after {
left: 16px;
background-color: $lever-enabled-color;
background-color: var(--lever-enabled-color);
}
}
}
@ -426,12 +404,12 @@ select:-moz-focusring {
}
.form-btn {
border: solid 1px $input-border-color;
border: solid 1px var(--input-border-color);
outline: none;
padding: 0 1rem;
line-height: 2rem;
background-color: $background-primary-color;
color: $primary-color;
background-color: var(--background-primary-color);
color: var(--primary-color);
display: inline-block;
margin-right: 0.6rem;
@ -446,21 +424,21 @@ select:-moz-focusring {
cursor: pointer;
&:focus, &:hover {
border-color: $primary-color;
outline-color: $primary-color;
border-color: var(--primary-color);
outline-color: var(--primary-color);
}
}
.btn-primary {
background-color: $primary-color;
color: $primary-text-color;
border-color: $primary-color;
background-color: var(--primary-color);
color: var(--primary-text-color);
border-color: var(--primary-color);
}
.btn-danger {
background-color: $error-color;
color: $error-text-color;
border-color: $error-color;
background-color: var(--error-color);
color: var(--error-text-color);
border-color: var(--error-color);
}
button::-moz-focus-inner, input::-moz-focus-inner, select::-moz-focus-inner {
@ -522,9 +500,28 @@ form {
float: left;
}
i {
font-size: 1.5rem;
padding: 0 0.5rem;
a {
i {
font-size: 1.8rem;
padding: 0 0.5rem;
position: relative;
}
&:first-child i::after {
content: '';
position: absolute;
left: 100%;
height: 100%;
width: 4rem;
}
&:last-child i::after {
content: '';
position: absolute;
height: 100%;
left: -4rem;
width: 4rem;
}
}
}
@ -589,8 +586,8 @@ form {
white-space: nowrap;
text-overflow: ellipsis;
background-color: $primary-color;
color: $primary-text-color;
background-color: var(--primary-color);
color: var(--primary-text-color);
padding: 0 0.5rem;
margin: 0.5rem;
@ -609,7 +606,7 @@ form {
}
&.drag {
box-shadow: 0 0.1rem 0.2rem rgba($text-primary-color, 0.8);
box-shadow: 0 0.1rem 0.2rem var(--shadow-color);
z-index: 2;
.calendar-tools {
@ -625,7 +622,7 @@ form {
top: 0;
width: 100%;
height: 100%;
background-color: $background-primary-color;
background-color: var(--background-primary-color);
opacity: 0.6;
}
@ -635,7 +632,7 @@ form {
.calendar[data-editable = "true"].edit {
.calendar-table {
width: calc(100% - 16rem);
border-right: solid 1px $table-border-color;
border-right: solid 1px var(--table-border-color);
}
.calendar-edit-main {
@ -655,8 +652,8 @@ form {
display: none;
z-index: 10;
border: solid 1px $input-border-color;
box-shadow: 0 0.1rem 0.2rem $primary-text-color;
border: solid 1px var(--input-border-color);
box-shadow: 0 0.1rem 0.2rem var(--primary-text-color);
a {
padding: 0.2rem;
@ -686,8 +683,8 @@ form {
white-space: nowrap;
text-overflow: ellipsis;
background-color: $primary-color;
color: $primary-text-color;
background-color: var(--primary-color);
color: var(--primary-text-color);
padding: 0 0.5rem;
@ -705,7 +702,7 @@ form {
}
&.drag {
box-shadow: 0 0.1rem 0.2rem rgba($text-primary-color, 0.8);
box-shadow: 0 0.1rem 0.2rem var(--shadow-color);
z-index: 2;
.calendar-tools {
@ -721,12 +718,12 @@ form {
top: 0;
width: 100%;
height: 100%;
background-color: $background-primary-color;
background-color: var(--background-primary-color);
opacity: 0.6;
}
&.error {
outline: solid 0.4rem $error-color;
outline: solid 0.4rem var(--error-color);
}
@include no-select()
@ -754,14 +751,14 @@ form {
height: 100%;
left: 0;
top: 0;
border-left: solid 1px $table-border-color;
border-left: solid 1px var(--table-border-color);
position: absolute;
}
}
}
.calendar-row {
border-top: solid 1px $table-border-color;
border-top: solid 1px var(--table-border-color);
line-height: 3rem;
height: 3rem;
@ -774,12 +771,12 @@ form {
height: 100%;
left: 0;
top: 0;
border-left: solid 1px $table-border-color;
border-left: solid 1px var(--table-border-color);
position: absolute;
}
&:hover {
background-color: $table-header-color;
background-color: var(--table-header-color);
}
.calendar-entry {
@ -796,7 +793,7 @@ form {
width: 6rem;
left: 0;
text-align: center;
border-right: solid 1px $table-border-color;
border-right: solid 1px var(--table-border-color);
}
.calendar-link {
@ -827,7 +824,7 @@ form {
height: 100%;
left: 0;
top: 0;
border-left: solid 1px $table-border-color;
border-left: solid 1px var(--table-border-color);
position: absolute;
}
}
@ -847,12 +844,12 @@ form {
width: 100%;
left: 0;
top: 0;
border-left: solid 1px $table-border-color;
border-left: solid 1px var(--table-border-color);
position: absolute;
}
&:hover {
background-color: $table-header-color;
background-color: var(--table-header-color);
}
.calendar-entry {
@ -873,7 +870,7 @@ form {
}
&:nth-child(4n + 2) .calendar-cell::before {
border-top: solid 1px $table-border-color;
border-top: solid 1px var(--table-border-color);
}
}
@ -920,8 +917,8 @@ form {
width: 1.1rem;
height: 0.5rem;
transform: rotate(-45deg);
border-left: solid 0.3rem $background-primary-color;
border-bottom: solid 0.3rem $background-primary-color;
border-left: solid 0.3rem var(--background-primary-color);
border-bottom: solid 0.3rem var(--background-primary-color);
}
}
@ -942,7 +939,7 @@ form {
height: 3rem;
border-radius: 1.5rem;
z-index: 1;
border: solid 0.1rem $text-primary-color;
border: solid 0.1rem var(--text-primary-color);
}
input:checked ~ label::before {
@ -954,8 +951,8 @@ form {
width: 1.1rem;
height: 0.5rem;
transform: rotate(-45deg);
border-left: solid 0.3rem $text-primary-color;
border-bottom: solid 0.3rem $text-primary-color;
border-left: solid 0.3rem var(--text-primary-color);
border-bottom: solid 0.3rem var(--text-primary-color);
}
label input {
@ -993,8 +990,8 @@ form {
text-align: center;
font-weight: bold;
color: $primary-text-color;
background: $primary-color;
color: var(--primary-text-color);
background: var(--primary-color);
}
}
@ -1018,8 +1015,8 @@ form {
display: none;
padding: 0.5rem 0;
background: $background-primary-color;
border: solid 1px $input-border-color;
background: var(--background-primary-color);
border: solid 1px var(--input-border-color);
border-radius: $border-radius;
span {
@ -1028,7 +1025,7 @@ form {
display: block;
&:hover {
background-color: $table-header-color;
background-color: var(--table-header-color);
}
}
@ -1068,7 +1065,7 @@ form {
top: 0;
left: 0;
font-size: 1.2rem;
color: $primary-color;
color: var(--primary-color);
line-height: 2rem;
padding: 0 1rem;
@ -1078,7 +1075,7 @@ form {
opacity: 0.5;
font-size: 1.2rem;
line-height: 2rem;
color: $text-primary-color;
color: var(--text-primary-color);
}
}
@ -1148,11 +1145,11 @@ form {
}
td {
border-top: solid 1px $table-border-color;
border-top: solid 1px var(--table-border-color);
}
th {
background-color: $table-header-color;
background-color: var(--table-header-color);
}
td, th {
@ -1161,7 +1158,7 @@ form {
}
.post-footer {
color: $text-secondary-color;
color: var(--text-secondary-color);
padding: 0 1rem;
font-size: 0.8rem;
font-weight: 400;
@ -1195,9 +1192,9 @@ form {
.post-edit-image {
width: 100%;
padding-top: 75%;
border: solid 1px $input-border-color;
border: solid 1px var(--input-border-color);
margin: 0;
background-color: $background-primary-color;
background-color: var(--background-primary-color);
background-position: center;
background-size: cover;
}
@ -1213,7 +1210,7 @@ form {
height: 1px;
left: 0;
right: 0;
background: $table-border-color;
background: var(--table-border-color);
}
}
@ -1258,3 +1255,49 @@ form {
flex-direction: row;
}
}
.footer {
height: 5rem;
}
.footer-credit {
float: left;
}
.footer-theme {
float: right;
line-height: 2rem;
margin-top: 0.5rem;
a {
display: block;
position: relative;
padding-left: 2.5rem;
&::after {
content: '';
width: 1.2rem;
height: 1.2rem;
border-radius: 100%;
position: absolute;
top: 1rem;
left: 1rem;
transform: translate(-50%, -50%);
border: solid 0.2rem transparent;
}
&.selected::after {
border-color: var(--primary-color) !important;
}
}
#theme-light::after {
background-color: #fff;
border-color: #fff;
}
#theme-dark::after {
background-color: #2d2d2d;
border-color: #2d2d2d;
}
}

View file

@ -9,6 +9,7 @@ import de.kif.backend.route.api.error
import de.kif.backend.util.WikiImporter
import de.kif.backend.view.MainTemplate
import de.kif.backend.view.MenuTemplate
import de.kif.backend.view.respondMain
import de.kif.common.RepositoryType
import de.kif.common.model.Permission
import io.ktor.application.call
@ -38,7 +39,7 @@ fun Route.account() {
val tracks = TrackRepository.all()
val wikiSections = WikiImporter.loadSections()
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.ACCOUNT

View file

@ -11,6 +11,7 @@ import de.kif.backend.repository.WorkGroupRepository
import de.kif.backend.view.MainTemplate
import de.kif.backend.view.MenuTemplate
import de.kif.backend.view.TableTemplate
import de.kif.backend.view.respondMain
import de.kif.common.CALENDAR_GRID_WIDTH
import de.kif.common.Search
import de.kif.common.model.Permission
@ -303,7 +304,7 @@ fun Route.calendar() {
.withLocale(KlockLocale.german)
.format(date)
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.CALENDAR
@ -315,13 +316,13 @@ fun Route.calendar() {
div("header") {
div("header-left") {
if (day - 1 in range) {
if (editable || day - 1 > range.start) {
a("/calendar/${day - 1}") { i("material-icons") { +"chevron_left" } }
}
span {
+dateString
}
if (day + 1 in range) {
if (editable || day + 1 < range.endInclusive) {
a("/calendar/${day + 1}") { i("material-icons") { +"chevron_right" } }
}
}
@ -400,7 +401,7 @@ fun Route.calendar() {
val list = WorkGroupRepository.all()
val room = RoomRepository.get(roomId) ?: return@get
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.WORK_GROUP

View file

@ -3,6 +3,7 @@ package de.kif.backend.route
import de.kif.backend.PortalSession
import de.kif.backend.UserPrinciple
import de.kif.backend.view.MainTemplate
import de.kif.backend.view.respondMain
import io.ktor.application.call
import io.ktor.auth.authenticate
import io.ktor.auth.principal
@ -32,7 +33,7 @@ fun Route.login() {
get {
val needLogin = call.sessions.get<PortalSession>() == null
if (needLogin) {
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
content {
div {
div {

View file

@ -8,6 +8,7 @@ import de.kif.backend.repository.PostRepository
import de.kif.backend.util.markdownToHtml
import de.kif.backend.view.MainTemplate
import de.kif.backend.view.MenuTemplate
import de.kif.backend.view.respondMain
import de.kif.common.formatDateTime
import de.kif.common.model.Permission
import de.kif.common.model.Post
@ -76,7 +77,7 @@ fun Route.overview() {
val postList = PostRepository.all().asReversed()
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.BOARD
@ -116,7 +117,7 @@ fun Route.overview() {
return@get
}
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.BOARD
@ -133,7 +134,7 @@ fun Route.overview() {
authenticateOrRedirect(Permission.POST) { user ->
val postId = call.parameters["id"]?.toLongOrNull() ?: return@get
val editPost = PostRepository.get(postId) ?: return@get
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.BOARD
@ -363,7 +364,7 @@ fun Route.overview() {
get("/post/new") {
authenticateOrRedirect(Permission.POST) { user ->
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.BOARD

View file

@ -5,6 +5,7 @@ import de.kif.backend.repository.RoomRepository
import de.kif.backend.view.MainTemplate
import de.kif.backend.view.MenuTemplate
import de.kif.backend.view.TableTemplate
import de.kif.backend.view.respondMain
import de.kif.common.Search
import de.kif.common.model.Permission
import de.kif.common.model.Room
@ -30,7 +31,8 @@ fun Route.room() {
authenticateOrRedirect(Permission.ROOM) { user ->
val search = call.parameters["search"] ?: ""
val list = RoomRepository.all()
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.ROOM
@ -110,7 +112,7 @@ fun Route.room() {
authenticateOrRedirect(Permission.ROOM) { user ->
val roomId = call.parameters["id"]?.toLongOrNull() ?: return@get
val editRoom = RoomRepository.get(roomId) ?: return@get
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.ROOM
@ -273,7 +275,7 @@ fun Route.room() {
get("/room/new") {
authenticateOrRedirect(Permission.ROOM) { user ->
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.ROOM

View file

@ -6,6 +6,7 @@ import de.kif.backend.repository.TrackRepository
import de.kif.backend.view.MainTemplate
import de.kif.backend.view.MenuTemplate
import de.kif.backend.view.TableTemplate
import de.kif.backend.view.respondMain
import de.kif.common.Search
import de.kif.common.model.Color
import de.kif.common.model.Permission
@ -88,7 +89,7 @@ fun Route.track() {
authenticateOrRedirect(Permission.WORK_GROUP) { user ->
val search = call.parameters["search"] ?: ""
val list = TrackRepository.all()
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.WORK_GROUP
@ -148,7 +149,7 @@ fun Route.track() {
authenticateOrRedirect(Permission.WORK_GROUP) { user ->
val trackId = call.parameters["id"]?.toLongOrNull() ?: return@get
val editTrack = TrackRepository.get(trackId) ?: return@get
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.WORK_GROUP
@ -217,7 +218,7 @@ fun Route.track() {
get("/track/new") {
authenticateOrRedirect(Permission.WORK_GROUP) { user ->
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.WORK_GROUP

View file

@ -7,6 +7,7 @@ import de.kif.backend.repository.UserRepository
import de.kif.backend.view.MainTemplate
import de.kif.backend.view.MenuTemplate
import de.kif.backend.view.TableTemplate
import de.kif.backend.view.respondMain
import de.kif.common.Search
import de.kif.common.model.Permission
import de.kif.common.model.User
@ -31,7 +32,7 @@ fun Route.user() {
authenticateOrRedirect(Permission.USER) { user ->
val search = call.parameters["search"] ?: ""
val list = UserRepository.all()
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.USER
@ -90,7 +91,7 @@ fun Route.user() {
authenticateOrRedirect(Permission.USER) { user ->
val userId = call.parameters["id"]?.toLongOrNull() ?: return@get
val editUser = UserRepository.get(userId) ?: return@get
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.USER
@ -183,7 +184,7 @@ fun Route.user() {
get("/user/new") {
authenticateOrRedirect(Permission.USER) { user ->
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.USER

View file

@ -6,6 +6,7 @@ import de.kif.backend.repository.WorkGroupRepository
import de.kif.backend.view.MainTemplate
import de.kif.backend.view.MenuTemplate
import de.kif.backend.view.TableTemplate
import de.kif.backend.view.respondMain
import de.kif.common.Search
import de.kif.common.model.*
import io.ktor.application.call
@ -27,7 +28,7 @@ fun Route.workGroup() {
authenticateOrRedirect(Permission.WORK_GROUP) { user ->
val search = call.parameters["search"] ?: ""
val list = WorkGroupRepository.all()
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.WORK_GROUP
@ -164,7 +165,7 @@ fun Route.workGroup() {
WorkGroupRepository.get(it)!!
}
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.WORK_GROUP
@ -527,7 +528,7 @@ fun Route.workGroup() {
get("/workgroup/new") {
authenticateOrRedirect(Permission.WORK_GROUP) { user ->
val tracks = TrackRepository.all()
call.respondHtmlTemplate(MainTemplate()) {
respondMain {
menuTemplate {
this.user = user
active = MenuTemplate.Tab.WORK_GROUP

View file

@ -1,13 +1,15 @@
package de.kif.backend.view
import de.kif.backend.Resources
import io.ktor.html.Placeholder
import io.ktor.html.Template
import io.ktor.html.TemplatePlaceholder
import io.ktor.html.insert
import io.ktor.application.ApplicationCall
import io.ktor.application.call
import io.ktor.html.*
import io.ktor.request.path
import io.ktor.response.respondRedirect
import io.ktor.util.pipeline.PipelineContext
import kotlinx.html.*
class MainTemplate : Template<HTML> {
class MainTemplate(private val theme: Theme) : Template<HTML> {
val content = Placeholder<HtmlBlockTag>()
val menuTemplate = TemplatePlaceholder<MenuTemplate>()
@ -27,6 +29,15 @@ class MainTemplate : Template<HTML> {
)
link(href = "/static/style/style.css", type = LinkType.textCss, rel = LinkRel.stylesheet)
when (theme) {
Theme.LIGHT -> {
// Ignore
}
Theme.DARK -> {
link(href = "/static/style/dark.css", type = LinkType.textCss, rel = LinkRel.stylesheet)
}
}
script(src = "/static/require.min.js") {}
script {
@ -43,6 +54,46 @@ class MainTemplate : Template<HTML> {
insert(content)
}
}
div("footer") {
div("container") {
div("footer-credit") {
}
div("footer-theme") {
for (it in Theme.values()) {
val name = it.name.toLowerCase()
a("?theme=$name", classes = if (theme == it) "selected" else "") {
id = "theme-$name"
+name.capitalize()
}
}
}
}
}
}
}
}
enum class Theme {
LIGHT, DARK
}
private fun String?.toTheme() = this?.toUpperCase()?.let { str ->
Theme.values().find { str == it.name }
} ?: Theme.LIGHT
suspend fun PipelineContext<Unit, ApplicationCall>.respondMain(body: MainTemplate.() -> Unit) {
val param = call.request.queryParameters["theme"]
if (param != null) {
call.response.cookies.append("theme", param.toTheme().name.toLowerCase())
call.respondRedirect(call.request.path())
} else {
call.respondHtmlTemplate(
MainTemplate(
call.request.cookies["theme"].toTheme()
),
body = body
)
}
}