From c409e04db91589682dca2231c282ce6441b0cef5 Mon Sep 17 00:00:00 2001 From: Darius Auding <Darius.auding@gmx.de> Date: Mon, 24 Jul 2023 16:16:45 +0200 Subject: [PATCH] Add Events block on index. --- sass/_calendar.scss | 490 ++++++++++++++++++ sass/style.scss | 1 + static/calendar.js | 12 + .../blocks/calendar/calendar_big.html | 110 ++++ .../blocks/calendar/calendar_compact.html | 96 ++++ templates/frontpage/blocks/events.html | 17 + typescript/Makefile | 3 + typescript/calendar.ts | 12 + 8 files changed, 741 insertions(+) create mode 100644 sass/_calendar.scss create mode 100644 static/calendar.js create mode 100644 templates/frontpage/blocks/calendar/calendar_big.html create mode 100644 templates/frontpage/blocks/calendar/calendar_compact.html create mode 100644 typescript/Makefile create mode 100644 typescript/calendar.ts diff --git a/sass/_calendar.scss b/sass/_calendar.scss new file mode 100644 index 00000000..6ea3e0bb --- /dev/null +++ b/sass/_calendar.scss @@ -0,0 +1,490 @@ +// Copyright (c) 2023 Wikiki (https://codepen.io/wikiki/pen/KvqKzK) + +@function powerNumber($number, $exp) { + $value: 1; + @if $exp > 0 { + @for $i from 1 through $exp { + $value: $value * $number; + } + } @else if $exp < 0 { + @for $i from 1 through -$exp { + $value: $value / $number; + } + } + @return $value; +} +@function colorLuminance($color) { + $color-rgb: ( + "red": red($color), + "green": green($color), + "blue": blue($color), + ); + @each $name, $value in $color-rgb { + $adjusted: 0; + $value: $value / 255; + @if $value < 0.03928 { + $value: $value / 12.92; + } @else { + $value: ($value + 0.055) / 1.055; + $value: powerNumber($value, 2); + } + $color-rgb: map-merge( + $color-rgb, + ( + $name: $value, + ) + ); + } + @return (map-get($color-rgb, "red") * 0.2126) + + (map-get($color-rgb, "green") * 0.7152) + + (map-get($color-rgb, "blue") * 0.0722); +} +@function findColorInvert($color) { + @if (colorLuminance($color) > 0.55) { + @return rgba(#000, 0.7); + } @else { + @return #fff; + } + + //////////////////////////////////////////////// + //////////////////////////////////////////////// + // 1. Initial variables + + // Colors +} +$black: hsl(0, 0%, 4%) !default; +$black-bis: hsl(0, 0%, 7%) !default; +$black-ter: hsl(0, 0%, 14%) !default; + +$grey-darker: hsl(0, 0%, 21%) !default; +$grey-dark: hsl(0, 0%, 29%) !default; +$grey: hsl(0, 0%, 48%) !default; +$grey-light: hsl(0, 0%, 71%) !default; +$grey-lighter: hsl(0, 0%, 86%) !default; + +$white-ter: hsl(0, 0%, 96%) !default; +$white-bis: hsl(0, 0%, 98%) !default; +$white: hsl(0, 0%, 100%) !default; + +$orange: hsl(14, 100%, 53%) !default; +$yellow: hsl(48, 100%, 67%) !default; +$green: hsl(141, 71%, 48%) !default; +$turquoise: hsl(171, 100%, 41%) !default; +$blue: hsl(217, 71%, 53%) !default; +$purple: hsl(271, 100%, 71%) !default; +$red: hsl(348, 100%, 61%) !default; + +// Typography +$family-sans-serif: + BlinkMacSystemFont, + -apple-system, + "Segoe UI", + "Roboto", + "Oxygen", + "Ubuntu", + "Cantarell", + "Fira Sans", + "Droid Sans", + "Helvetica Neue", + "Helvetica", + "Arial", + sans-serif !default; +$family-monospace: monospace !default; +$render-mode: optimizeLegibility !default; + +$size-1: 3rem !default; +$size-2: 2.5rem !default; +$size-3: 2rem !default; +$size-4: 1.5rem !default; +$size-5: 1.25rem !default; +$size-6: 1rem !default; +$size-7: 0.75rem !default; + +$weight-light: 300 !default; +$weight-normal: 400 !default; +$weight-semibold: 500 !default; +$weight-bold: 700 !default; + +// Body +$body-background: #fff !default; +$body-size: 16px !default; + +// Responsiveness +// 960, 1152, and 1344 have been chosen because they are divisible by both 12 and 16 +$tablet: 769px !default; +// 960px container + 40px +$desktop: 1000px !default; +// 1152px container + 40 +$widescreen: 1192px !default; +// 1344px container + 40 +$fullhd: 1384px !default; + +// Miscellaneous +$easing: ease-out !default; +$radius-small: 2px !default; +$radius: 3px !default; +$radius-large: 5px !default; +$speed: 86ms !default; + +//////////////////////////////////////////////// +//////////////////////////////////////////////// +// 2. Primary colors + +$primary: $teckids-orange; + +$info: $teckids-blue; +$success: map-get($project-colors, hack-n-fun); +$warning: map-get($project-colors, schul-frei); +$danger: map-get($project-colors, indiedact); + +$light: $white-ter !default; +$dark: $grey-darker !default; + +//////////////////////////////////////////////// +//////////////////////////////////////////////// +// 3. Applied variables + +// Invert colors + +$primary-invert: findColorInvert($primary); +$info-invert: findColorInvert($info); +$success-invert: findColorInvert($success); +$warning-invert: findColorInvert($warning); +$danger-invert: findColorInvert($danger); +$light-invert: $dark; +$dark-invert: $light; + +// General colors +$background: $white-ter !default; + +$border: $grey-lighter !default; +$border-hover: $grey-light !default; + +// Text colors +$text: $grey-dark !default; +$text-invert: findColorInvert($text) !default; +$text-light: $grey !default; +$text-strong: $grey-darker !default; + +// Code colors +$code: $red !default; +$code-background: $background !default; + +$pre: $text !default; +$pre-background: $background !default; + +// Link colors +$link: $primary !default; +$link-invert: $primary-invert !default; +$link-visited: $purple !default; + +$link-hover: $grey-darker !default; +$link-hover-border: $grey-light !default; + +$link-focus: $grey-darker !default; +$link-focus-border: $primary !default; + +$link-active: $grey-darker !default; +$link-active-border: $grey-dark !default; + +// Typography +$family-primary: $family-sans-serif !default; +$family-code: $family-monospace !default; + +$size-small: $size-7 !default; +$size-normal: $size-6 !default; +$size-medium: $size-5 !default; +$size-large: $size-4 !default; + +//////////////////////////////////////////////// +//////////////////////////////////////////////// +// 4. Lists and maps + +$colors: ( + "white": ( + $white, + $black, + ), + "black": ( + $black, + $white, + ), + "light": ( + $light, + $light-invert, + ), + "dark": ( + $dark, + $dark-invert, + ), + "primary": ( + $primary, + $primary-invert, + ), + "info": ( + $info, + $info-invert, + ), + "success": ( + $success, + $success-invert, + ), + "warning": ( + $warning, + $warning-invert, + ), + "danger": ( + $danger, + $danger-invert, + ), +); + +$sizes: $size-1 $size-2 $size-3 $size-4 $size-5 $size-6 $size-7 !default; + +$calendar-border: 0.1rem solid $grey-lighter !default; +$calendar-border-radius: $radius-small !default; + +.calendar { + border: $calendar-border; + border-radius: $calendar-border-radius; + display: block; + min-width: 28rem; + text-align: center; + .calendar-nav { + -webkit-align-items: center; + align-items: center; + background: $primary; + color: $white; + border-top-left-radius: $radius-small; + border-top-right-radius: $radius-small; + display: flex; + display: -ms-flexbox; + display: -webkit-flex; + -ms-flex-align: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + font-size: $size-4; + padding: 0.5rem; + .calendar-nav-left, + .calendar-nav-right { + -ms-flex-preferred-size: auto; + flex-basis: auto; + -webkit-box-flex: 0; + -ms-flex-positive: 0; + flex-grow: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + .button { + text-decoration: none; + color: $white; + &:hover { + background: transparent; + color: $grey-lighter; + } + } + } + .calendar-nav-left { + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + } + .calendar-nav-right { + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; + } + } + .calendar-header, + .calendar-body { + display: flex; + display: -ms-flexbox; + display: -webkit-flex; + -ms-flex-pack: center; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-justify-content: center; + justify-content: center; + padding: 0.2rem 0; + } + .calendar-header .calendar-date, + .calendar-body .calendar-date { + -webkit-flex: 0 0 14.28%; + -ms-flex: 0 0 14.28%; + flex: 0 0 14.28%; + max-width: 14.28%; + } + .calendar-header { + background: darken($primary, 5%); + color: $white; + font-size: $size-6; + } + .calendar-body { + color: $grey; + } + + .calendar-date { + border: 0; + padding: 0.4rem; + .date-item { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background: transparent; + border: 0.1rem solid transparent; + border-radius: 100%; + color: $text; + cursor: pointer; + height: 2.8rem; + line-height: 2rem; + outline: none; + padding: 0.3rem; + position: relative; + text-align: center; + text-decoration: none; + transition: all 0.2s ease; + vertical-align: middle; + white-space: nowrap; + width: 2.8rem; + &.is-today { + border-color: $primary; + color: $primary; + } + &.is-active { + background: $primary; + border-color: $primary; + color: #fff; + } + &.is-highlighted { + background: findLightColor($primary); + } + &:focus { + background: $primary; + border-color: $primary; + color: $white; + text-decoration: none; + } + &:hover { + background: findLightColor($primary); + border-color: $primary; + color: $grey; + text-decoration: none; + } + } + &.is-disabled { + .date-item, + .calendar-event { + cursor: default; + opacity: 0.25; + pointer-events: none; + } + } + } + .calendar-range { + position: relative; + &::before { + background: lighten($primary, 50%); + content: ""; + height: 2.8rem; + left: 0; + position: absolute; + right: 0; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); + } + &.range-start::before { + left: 50%; + } + &.range-end::before { + right: 50%; + } + .date-item { + color: $primary; + } + } + &.is-calendar-large { + .calendar-body { + padding: 0; + .calendar-date { + border-bottom: $calendar-border; + border-right: $calendar-border; + display: flex; + display: -ms-flexbox; + display: -webkit-flex; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + height: 11rem; + padding: 0; + &:nth-child(7n) { + border-right: 0; + } + false { + border-bottom: 0; + } + } + } + .date-item { + -webkit-align-self: flex-end; + align-self: flex-end; + -ms-flex-item-align: end; + height: 2.8rem; + margin-right: 0.5rem; + margin-top: 0.5rem; + } + .calendar-range { + &::before { + top: 1.9rem; + } + &.range-start::before { + left: auto; + width: 1.9rem; + } + &.range-end::before { + right: 1.9rem; + } + } + .calendar-events { + -webkit-flex-grow: 1; + flex-grow: 1; + -ms-flex-positive: 1; + line-height: 1; + overflow-y: auto; + padding: 0.5rem; + } + .calendar-event { + background-color: $info; + border-radius: $radius-small; + color: $white; + display: block; + font-size: 1rem; + margin: 0.2rem auto; + overflow: hidden; + padding: 0.3rem 0.4rem; + text-align: left; + text-overflow: ellipsis; + vertical-align: baseline; + white-space: nowrap; + @each $name, $pair in $colors { + $color: nth($pair, 1); + $color-invert: nth($pair, 2); + &.is-#{$name} { + background-color: $color; + color: $color-invert; + } + } + } + } +} diff --git a/sass/style.scss b/sass/style.scss index 7dee0d1d..8689be9d 100644 --- a/sass/style.scss +++ b/sass/style.scss @@ -8,3 +8,4 @@ $family-sans-serif: "Roboto", sans-serif; @import "./_menu.scss"; @import "./_content.scss"; +@import "./_calendar"; diff --git a/static/calendar.js b/static/calendar.js new file mode 100644 index 00000000..dd19ee25 --- /dev/null +++ b/static/calendar.js @@ -0,0 +1,12 @@ +document.addEventListener("DOMContentLoaded", function () { + var month = document.getElementById("year_and_month"); + if (month == null) { + return; + } + var date = new Date(); + month.innerHTML = + "" + + date.toLocaleString("de-de", { month: "long" }) + + " " + + date.getFullYear(); +}); diff --git a/templates/frontpage/blocks/calendar/calendar_big.html b/templates/frontpage/blocks/calendar/calendar_big.html new file mode 100644 index 00000000..b5824031 --- /dev/null +++ b/templates/frontpage/blocks/calendar/calendar_big.html @@ -0,0 +1,110 @@ +<!-- Copyright (c) 2023 Wikiki (https://codepen.io/wikiki/pen/KvqKzK) --> + +<div class="calendar is-calendar-large"> + <script src="/calendar.js"></script> + <div class="calendar-nav"> + <div class="calendar-nav-left"> + <button class="button is-link"> + <i class="fa fa-chevron-left"></i> + </button> + </div> + <div>March 2017</div> + <div class="calendar-nav-right"> + <button class="button is-link"> + <i class="fa fa-chevron-right"></i> + </button> + </div> + </div> + <div class="calendar-container"> + <!-- Days of the week --> + <div class="calendar-header"> + <div class="calendar-date">Sun</div> + <div class="calendar-date">Mon</div> + <div class="calendar-date">Tue</div> + <div class="calendar-date">Wed</div> + <div class="calendar-date">Thu</div> + <div class="calendar-date">Fri</div> + <div class="calendar-date">Sat</div> + </div> + <div class="calendar-body"> + <div class="calendar-date disabled"> + <button class="date-item">26</button> + </div> + <div class="calendar-date disabled"> + <button class="date-item">27</button> + <div class="calendar-events"> + <a class="calendar-event">Default event</a> + </div> + </div> + <div class="calendar-date disabled"> + <button class="date-item">28</button> + </div> + <div class="calendar-date"><button class="date-item">1</button></div> + <div class="calendar-date"><button class="date-item">2</button></div> + <div class="calendar-date"><button class="date-item">3</button></div> + <div class="calendar-date tooltip" data-tooltip="Today"> + <button class="date-item date-today">4</button> + </div> + <div class="calendar-date"> + <button class="date-item" disabled="">5</button> + </div> + <div class="calendar-date"><button class="date-item">6</button></div> + <div class="calendar-date"><button class="date-item">7</button></div> + <div class="calendar-date tooltip" data-tooltip="You have appointments"> + <button class="date-item badge">8</button> + <div class="calendar-events"> + <a class="calendar-event is-primary">Primary event</a> + <a class="calendar-event is-warning">Warning event</a> + <a class="calendar-event is-danger">Danger event</a> + </div> + </div> + <div class="calendar-date"><button class="date-item">9</button></div> + <div class="calendar-date"><button class="date-item">10</button></div> + <div class="calendar-date"><button class="date-item">11</button></div> + <div class="calendar-date"> + <button class="date-item">12</button> + <div class="calendar-events"> + <a class="calendar-event">Default event</a> + </div> + </div> + <div class="calendar-date"><button class="date-item">13</button></div> + <div class="calendar-date"><button class="date-item">14</button></div> + <div class="calendar-date"><button class="date-item">15</button></div> + <div class="calendar-date calendar-range range-start"> + <button class="date-item is-active">16</button> + </div> + <div class="calendar-date calendar-range"> + <button class="date-item">17</button> + </div> + <div class="calendar-date calendar-range"> + <button class="date-item">18</button> + </div> + <div class="calendar-date calendar-range"> + <button class="date-item">19</button> + </div> + <div class="calendar-date calendar-range range-end"> + <button class="date-item is-active">20</button> + <div class="calendar-events"> + <a class="calendar-event is-success">Success event</a> + </div> + </div> + <div class="calendar-date"><button class="date-item">21</button></div> + <div class="calendar-date"><button class="date-item">22</button></div> + <div class="calendar-date"><button class="date-item">23</button></div> + <div class="calendar-date"><button class="date-item">24</button></div> + <div class="calendar-date"><button class="date-item">25</button></div> + <div class="calendar-date"><button class="date-item">26</button></div> + <div class="calendar-date"><button class="date-item">27</button></div> + <div class="calendar-date"><button class="date-item">28</button></div> + <div class="calendar-date"><button class="date-item">29</button></div> + <div class="calendar-date"><button class="date-item">30</button></div> + <div class="calendar-date"><button class="date-item">31</button></div> + <div class="calendar-date disabled"> + <button class="date-item">1</button> + <div class="calendar-events"> + <a class="calendar-event">Second default event</a> + </div> + </div> + </div> + </div> +</div> diff --git a/templates/frontpage/blocks/calendar/calendar_compact.html b/templates/frontpage/blocks/calendar/calendar_compact.html new file mode 100644 index 00000000..648c9c69 --- /dev/null +++ b/templates/frontpage/blocks/calendar/calendar_compact.html @@ -0,0 +1,96 @@ +<!-- Copyright (c) 2023 Wikiki (https://codepen.io/wikiki/pen/KvqKzK) --> + +<script src="/calendar.js"></script> +<div class="column is-4"> + <div class="calendar"> + <div class="calendar-nav"> + <div class="calendar-nav-left"> + <button class="button is-link"> + <i class="fa fa-chevron-left"></i> + </button> + </div> + <div id="year_and_month"></div> + <div class="calendar-nav-right"> + <button class="button is-link"> + <i class="fa fa-chevron-right"></i> + </button> + </div> + </div> + <div class="calendar-container"> + <!-- Header with Day titles --> + <div class="calendar-header"> + <div class="calendar-date">Mon</div> + <div class="calendar-date">Die</div> + <div class="calendar-date">Mit</div> + <div class="calendar-date">Don</div> + <div class="calendar-date">Fre</div> + <div class="calendar-date">Sam</div> + <div class="calendar-date">Son</div> + </div> + + <div class="calendar-body"> + <!-- Every item is a date --> + + <div class="calendar-date is-disabled"> + <button class="date-item">26</button> + </div> + <div class="calendar-date is-disabled"> + <button class="date-item">27</button> + </div> + <div class="calendar-date is-disabled"> + <button class="date-item">28</button> + </div> + <div class="calendar-date"><button class="date-item">1</button></div> + <div class="calendar-date"><button class="date-item">2</button></div> + <div class="calendar-date"><button class="date-item">3</button></div> + <div class="calendar-date"> + <button class="date-item is-today">4</button> + </div> + <div class="calendar-date"> + <button class="date-item" disabled="">5</button> + </div> + <div class="calendar-date"><button class="date-item">6</button></div> + <div class="calendar-date"><button class="date-item">7</button></div> + <div class="calendar-date"> + <button class="date-item badge is-highlighted">8</button> + </div> + <div class="calendar-date"><button class="date-item">9</button></div> + <div class="calendar-date"><button class="date-item">10</button></div> + <div class="calendar-date"><button class="date-item">11</button></div> + <div class="calendar-date"><button class="date-item">12</button></div> + <div class="calendar-date"><button class="date-item">13</button></div> + <div class="calendar-date"><button class="date-item">14</button></div> + <div class="calendar-date"><button class="date-item">15</button></div> + <div class="calendar-date calendar-range range-start"> + <button class="date-item is-highlighted">16</button> + </div> + <div class="calendar-date calendar-range"> + <button class="date-item">17</button> + </div> + <div class="calendar-date calendar-range"> + <button class="date-item">18</button> + </div> + <div class="calendar-date calendar-range"> + <button class="date-item">19</button> + </div> + <div class="calendar-date calendar-range range-end is-highlighted"> + <button class="date-item is-highlighted">20</button> + </div> + <div class="calendar-date"><button class="date-item">21</button></div> + <div class="calendar-date"><button class="date-item">22</button></div> + <div class="calendar-date"><button class="date-item">23</button></div> + <div class="calendar-date"><button class="date-item">24</button></div> + <div class="calendar-date"><button class="date-item">25</button></div> + <div class="calendar-date"><button class="date-item">26</button></div> + <div class="calendar-date"><button class="date-item">27</button></div> + <div class="calendar-date"><button class="date-item">28</button></div> + <div class="calendar-date"><button class="date-item">29</button></div> + <div class="calendar-date"><button class="date-item">30</button></div> + <div class="calendar-date"><button class="date-item">31</button></div> + <div class="calendar-date is-disabled"> + <button class="date-item">1</button> + </div> + </div> + </div> + </div> +</div> diff --git a/templates/frontpage/blocks/events.html b/templates/frontpage/blocks/events.html index e69de29b..38324a78 100644 --- a/templates/frontpage/blocks/events.html +++ b/templates/frontpage/blocks/events.html @@ -0,0 +1,17 @@ +<section class="section"> + <div class="container"> + <div class="columns is-centered is-half"> + <h1 class="title is-1">Events</h1> + </div> + <div class="columns"> + <div class="column is-two-thirds"> + <div class="notification">Event 1</div> + <div class="notification">Event 2</div> + <div class="notification">Event 3</div> + </div> + <aside> + {% include "frontpage/blocks/calendar/calendar_compact.html" %} + </aside> + </div> + </div> +</section> diff --git a/typescript/Makefile b/typescript/Makefile new file mode 100644 index 00000000..3583df36 --- /dev/null +++ b/typescript/Makefile @@ -0,0 +1,3 @@ + +calendar: + tsc --outFile ../static/calendar.js ./calendar.ts diff --git a/typescript/calendar.ts b/typescript/calendar.ts new file mode 100644 index 00000000..8febfefc --- /dev/null +++ b/typescript/calendar.ts @@ -0,0 +1,12 @@ +document.addEventListener("DOMContentLoaded", () => { + let month = document.getElementById("year_and_month"); + if (month == null) { + return; + } + let date = new Date(); + month.innerHTML = + "" + + date.toLocaleString("de-de", { month: "long" }) + + " " + + date.getFullYear(); +}); -- GitLab