Add dark mode
This commit is contained in:
parent
df8f04099a
commit
f90a4dddba
12 changed files with 296 additions and 133 deletions
39
src/jsMain/resources/style/_color.scss
Normal file
39
src/jsMain/resources/style/_color.scss
Normal 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;
|
||||
}
|
||||
}
|
21
src/jsMain/resources/style/dark.scss
Normal file
21
src/jsMain/resources/style/dark.scss
Normal 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;
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue