most of it

This commit is contained in:
2023-09-18 17:31:11 +00:00
parent 5f27fe0c5b
commit 481308522f
380 changed files with 3015 additions and 2480 deletions

View File

@@ -0,0 +1,142 @@
.underline {
display: inline;
position: relative;
overflow: hidden;
}
.underline:after {
content: "";
position: absolute;
z-index: 10000;
right: 0;
width: 0;
bottom: -2px;
background: var(--background-color);
height: 4px;
transition: width 0.5s ease-in;
}
.underline:hover:after,
.underline:focus:after,
.underline:active:after {
left: 0;
right: auto;
width: 100%;
}
.fill {
display: inline;
position: relative;
overflow: hidden;
}
.fill:hover {
color: var(--background-color) !important;
div {
position: relative;
z-index: 2;
}
}
.fill:after {
content: "";
position: absolute;
z-index: 1;
right: 0;
top: 0px;
bottom: 0px;
width: 0px;
background: var(--opposite-bg-color);
transition: width 0.5s ease-in;
}
.fill:hover:after,
.fill:focus:after,
.fill:active:after {
right: auto;
width: 100%;
left: 0px;
}
@keyframes underlineEffect {
0% {
width: 0;
}
100% {
width: 100%;
}
}
swiper-slide {
&:hover {
h1.active .underline {
animation-play-state: paused;
}
}
}
.titles {
h1 {
.underline {
position: absolute;
z-index: 10000;
left: 0px;
bottom: -10px;
background: var(--opposite-bg-color);
height: 5px;
width: 0;
animation: underlineEffect 4s linear forwards;
@media @tablet {
height: 10px;
}
}
&:not(.active) .underline {
animation: none;
}
}
}
.swiper-button-prev,
.swiper-button-next {
color: var(--normal-font-color) !important;
height: 70px !important;
width: 70px !important;
bottom: 0px !important;
top: initial !important;
transform: scale(0.5) !important;
}
.swiper-button-prev {
right: 18% !important;
left: initial !important;
transform-origin: left !important;
}
.swiper-button-next {
right: 3% !important;
transform-origin: right;
}
@media @tablet {
.swiper-button-prev,
.swiper-button-next {
bottom: initial !important;
top: 120px !important;
transform: scale(0.8) !important;
transform-origin: center !important;
}
.swiper-button-prev {
left: 0% !important;
right: initial !important;
transform-origin: left !important;
}
.swiper-button-next {
right: 0% !important;
transform-origin: right !important;
}
}
@media @desktop {
.swiper-button-prev,
.swiper-button-next {
top: 125px !important;
transform: scale(1) !important;
}
}

View File

@@ -1,26 +1,33 @@
@background-color: white;
@normal-font-color: #333333;
@hover-color: #dee2e6;
@heading-font-color: #4b678b;
@link-font-color: #4b678b;
@banner-color: #06d6a0;
:root {
--background-color: white;
--background-color-90: #ffffffe6;
--normal-font-color: #333333;
--normal-font-color-12: rgba(51, 51, 51, 0.12);
--hover-color: #dee2e6;
--heading-font-color: #672129;
--link-font-color: #672129;
--banner-color: #06d6a0;
--opposite-bg-color: #000;
--opposite-bg-color-80: rgba(0, 0, 0, 0.8);
--opposite-bg-color-5: rgba(0, 0, 0, 0.05);
}
@desktop: ~"only screen and (min-width: 1024px)";
@tablet: ~"only screen and (min-width: 768px)";
@mobile: ~"only screen and (min-width: 100px)";
@body-fontsize-mobile: 17px;
@body-fontsize-pc: 24px;
@body-fontsize-mobile: 16px;
@body-lineheight-mobile: 130%;
@body-lineheight-pc: 130%;
@body-maxwidth: 1800px;
@body-small-maxwidth: 1200px;
/* Allgemeine Stile */
/* roboto-condensed-regular - latin */
body.darkTheme {
--background-color: #1a1a1a; /* softer than #121212 */
--background-color-90: rgba(26, 26, 26, 0.9);
--normal-font-color: #d1d1d1; /* off-white, less harsh */
--normal-font-color-12: rgba(209, 209, 209, 0.12);
--hover-color: #404040; /* subtle change for hover */
--heading-font-color: #9fb3c7; /* slightly brighter for better readability */
--link-font-color: #9fb3c7;
--banner-color: #04a577; /* a cooler shade for the banner */
--opposite-bg-color: #fafafa; /* off-white */
--opposite-bg-color-80: rgba(250, 250, 250, 0.8);
--opposite-bg-color-5: rgba(250, 250, 250, 0.05);
.row ul li::before {
background-image: url("../../../../media/arrow-right-darkt.svg") !important;
}
}
* {
font-family: "Roboto Condensed", sans-serif;
@@ -30,14 +37,13 @@
}
body {
font-family: "Roboto Condensed", sans-serif;
color: #333 !important;
height: 100%;
background-color: #f9f9f9;
overflow-x: hidden !important;
}
body {
background-color: @background-color;
color: var(--normal-font-color);
font-family: "Roboto Condensed", sans-serif;
background-color: var(--background-color);
min-height: 100vh;
display: flex;
justify-content: center;
@@ -69,8 +75,8 @@ ol {
/* Links */
a {
color: @link-font-color;
text-decoration: none;
color: var(--link-font-color);
text-decoration: underline;
font-weight: 700;
}
@@ -94,20 +100,17 @@ td {
}
th {
background-color: #f4f4f4;
background-color: var(--background-color-90);
}
button {
background-color: inherit;
border: none;
cursor: pointer;
font-size: inherit;
color: #333;
color: var(--normal-font-color);
}
input,
select {
color: #333;
color: var(--normal-font-color);
width: 100%;
}
.text-container {
}

View File

@@ -0,0 +1,6 @@
swiper-container {
height: auto;
width: 100%;
max-width: 1200px;
padding: 20px !important;
}

View File

@@ -1,19 +1,21 @@
.swiper-button-prev,
.swiper-button-next {
transform-origin: left;
color: #333;
transform: scale(0.3);
background-color: rgba(255, 255, 255, 0.6);
top: 50%;
padding: 10px;
height: 70px;
width: 70px;
border-radius: 50px;
}
.swiper-button-prev {
left: 6%;
}
.swiper-button-next {
right: 6%;
transform-origin: right;
.images {
.swiper-button-prev,
.swiper-button-next {
transform-origin: left;
color: var(--normal-font-color);
transform: scale(0.3);
background-color: rgba(255, 255, 255, 0.6);
top: 50%;
padding: 10px;
height: 70px;
width: 70px;
border-radius: 50px;
}
.swiper-button-prev {
left: 6%;
}
.swiper-button-next {
right: 6%;
transform-origin: right;
}
}

View File

@@ -1,13 +1,4 @@
@background-color: white;
@normal-font-color: #333333;
@hover-color: #dee2e6;
@heading-font-color: #4b678b;
@link-font-color: #4b678b;
@banner-color: #06d6a0;
@desktop: ~"only screen and (min-width: 1024px)";
@tablet: ~"only screen and (min-width: 768px)";
@mobile: ~"only screen and (min-width: 100px)";
@body-fontsize-mobile: 17px;
@body-fontsize-pc: 24px;
@@ -17,3 +8,7 @@
@body-maxwidth: 1800px;
@body-small-maxwidth: 1200px;
@desktop: ~"only screen and (min-width: 1024px)";
@tablet: ~"only screen and (min-width: 768px)";
@mobile: ~"only screen and (min-width: 100px)";

View File

@@ -5,32 +5,24 @@
<div class="footer">
<div class="infos">
<h3>Wasserski Erfurt</h3>
<h3>AllKids Erfurt</h3>
<div class="infos-inner">
<div class="upper">
<p>Inh. Michael Sadlon</p>
<p>Zum Nordstrand 4</p>
<p>99085 Erfurt</p>
<p>Inh. Grit Grenzdörfer</p>
<p>Eichenstraße 8</p>
<p>99084 Erfurt</p>
</div>
<div class="lower">
<p>Tel.: 0361 - 796 876 4</p>
<p>Fax.: 0361 - 796 876 8</p>
<p>Email: info@wasserski-erfurt.de</p>
<p>Tel.: <a href="tel:+491784124555">0178 4124555</a></p>
<p>Email: <a href="mailto:kiro0206@icloud.com">kiro0206@icloud.com</a></p>
</div>
</div>
<div class="social">
<a href="https://www.instagram.com/wasserski_erfurt/">
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M11.7 3h12.6c4.8 0 8.7 3.9 8.7 8.7v12.6a8.7 8.7 0 0 1-8.7 8.7H11.7C6.9 33 3 29.1 3 24.3V11.7A8.7 8.7 0 0 1 11.7 3zm-.3 3A5.4 5.4 0 0 0 6 11.4v13.2c0 2.985 2.415 5.4 5.4 5.4h13.2a5.4 5.4 0 0 0 5.4-5.4V11.4C30 8.415 27.585 6 24.6 6H11.4zm14.475 2.25a1.875 1.875 0 1 1 0 3.75 1.875 1.875 0 0 1 0-3.75zM18 10.5a7.5 7.5 0 1 1 0 15 7.5 7.5 0 0 1 0-15zm0 3a4.5 4.5 0 1 0 0 9 4.5 4.5 0 0 0 0-9z"
fill="#333333"></path>
</svg>
</a>
<a href="https://www.facebook.com/wasserskierfurt/">
<a href="https://www.facebook.com/allkids.erfurt/">
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M18 3.06c-8.25 0-15 6.735-15 15.03 0 7.5 5.49 13.725 12.66 14.85v-10.5h-3.81v-4.35h3.81v-3.315c0-3.765 2.235-5.835 5.67-5.835 1.635 0 3.345.285 3.345.285v3.705h-1.89c-1.86 0-2.445 1.155-2.445 2.34v2.82h4.17l-.675 4.35H20.34v10.5A15 15 0 0 0 33 18.09c0-8.295-6.75-15.03-15-15.03z"
fill="#333333"></path>
fill="var(--normal-font-color)"></path>
</svg>
</a>
</div>
@@ -39,11 +31,19 @@
{#each $serviceNavigation?.elemente || [] as service, i (i)}
<button
on:click="{() => {
navigate(`${$sites[service.seite]?.path}`)
navigate(`${$sites[service.seite || '']?.path}`)
}}">{service?.name}</button
>
{/each}
</div>
<button
on:click="{() => {
const body = document.querySelector('body')
if (body) body.classList.toggle('darkTheme')
}}"
>
toggletheme
</button>
</div>
<style lang="less">
@@ -58,7 +58,7 @@
display: flex;
justify-content: space-between;
max-width: calc(@body-maxwidth - min(9vw, 200px));
background-color: @hover-color;
background-color: var(--hover-color);
padding: min(4.5vw, 100px) min(4.5vw, 100px) 0px min(4.5vw, 100px);
}
.infos {
@@ -91,17 +91,15 @@
@media @tablet {
gap: 40px;
}
height: 350px;
min-height: 350px;
.infos-inner {
flex-direction: column;
}
}
.footer {
}
}
@media @desktop {
.footer {
height: 350px;
min-height: 350px;
.infos-inner {
gap: 5vw;
flex-direction: row;

View File

@@ -1,7 +1,7 @@
<script lang="ts">
export let cookieName
export let cookieName: string
export let backgroundUrl = ""
export let textPosition = "center"
export let textPosition: "oben" | "mitte" | "unten" = "mitte"
export let background = ""
let contentShown = false
const positions = {
@@ -11,15 +11,16 @@
}
window.addEventListener("ccAccept", (e) => {
// @ts-ignore
if (e.detail[1] == cookieName) contentShown = true
})
//isCookieSet isnt really precise
function checkCookie(name) {
function checkCookie(cookieName: string) {
// Get all cookies
var allCookies = decodeURIComponent(document.cookie)
// Split into individual cookies
var cookies = allCookies.split(";")
var ccTagCookies = []
var ccTagCookies: string[] = []
cookies.forEach((e) => {
e.includes("ccTags") ? (ccTagCookies = e.split(",")) : void 0
})

View File

@@ -3,18 +3,19 @@
import CookieSet from "./cookieSet.svelte"
$: iframeTitle = "testrest"
let setHeight = (element) => {
let setHeight = (element: HTMLIFrameElement) => {
element.style.height = (element.offsetWidth / 16) * 9 + "px"
}
</script>
<CookieSet cookieName="{'googleMaps'}" textPosition="{'unten'}" background="{'rgba(44, 44, 44, 0.4)'}">
<!-- svelte-ignore a11y-missing-attribute -->
<iframe
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d20097.11535738499!2d11.016094258611309!3d50.976613538609506!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47a47295445dec17%3A0x78ec05d774043a43!2sall%20kids%20-%20Secondhand%20Kinderbekleidung!5e0!3m2!1sde!2sde!4v1694951373813!5m2!1sde!2sde"
use:setHeight
id="iframe"
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2510.8843160281504!2d11.046507612986247!3d50.99980984753832!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47a46d575a841fe1%3A0xd6703e9ebe1ca279!2sErfurt%20Wasserski-%20und%20Wakeboardanlage!5e0!3m2!1sde!2sde!4v1682691189533!5m2!1sde!2sde"
style="border:0;"
allowfullscreen=""
allowfullscreen="{true}"
loading="lazy"
referrerpolicy="no-referrer-when-downgrade"></iframe>
</CookieSet>

View File

@@ -1,7 +1,6 @@
<script lang="ts">
import DesktopHeader from "./desktop.svelte"
import MobileHeader from "./mobile.svelte"
import { navigation } from "../../stores"
</script>
<main class="headercontainer">
@@ -18,7 +17,17 @@
<style global lang="less">
@import "../../assets/css/main.less";
@import "../../assets/css/variables.less";
@desktop: ~"only screen and (min-width: 1440px)";
.HP {
h2 {
font-size: 2.1rem !important;
@media @tablet {
font-size: 3.2rem !important;
}
}
}
.ignore {
display: none !important;
@@ -28,6 +37,7 @@
position: relative;
height: 100%;
width: 100%;
}
.placeholder {
height: 105px;
@@ -39,8 +49,9 @@
top: 0px;
justify-content: space-between;
width: 100%;
color: #333;
color: var(--normal-font-color);
height: 105px;
}
@media @desktop {
.headercontainer,

View File

@@ -10,9 +10,10 @@
else siteContainer.style.overflow = "initial"
}
async function changeSubmenu(e, i) {
async function changeSubmenu(e: EventTarget & HTMLLIElement, i: string | number) {
changeStateOfSite(true)
let submenu = document.getElementById("submenu-container")
if (!submenu) return
submenu.style.height = "calc(100vh - 120px)"
submenu.classList.add("show-submenu")
@@ -21,23 +22,27 @@
element.classList.remove("shown")
})
let shownMenu = document.getElementById("submenu-" + i)
if (!shownMenu) return
shownMenu.classList.add("shown")
}
let hoverTimeout
let hoverTimeout: string | number | NodeJS.Timeout | undefined
</script>
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<ul
class="menu"
on:mouseover="{(e) => {
clearTimeout(hoverTimeout)
hoverTimeout = setTimeout(() => {
let element = document.getElementById('submenu-container')
element.style.height = '0vh'
changeStateOfSite(false)
element.classList.remove('show-submenu')
let elements = document.getElementsByClassName('select-menu')
Array.from(elements).forEach((e) => e.classList.remove('select-menu'))
if (element) {
element.style.height = '0vh'
changeStateOfSite(false)
element.classList.remove('show-submenu')
let elements = document.getElementsByClassName('select-menu')
Array.from(elements).forEach((e) => e.classList.remove('select-menu'))
}
}, 500)
}}"
on:mouseleave="{() => {
@@ -48,27 +53,34 @@
class="logo-container"
on:click="{() => {
let element = document.getElementById('submenu-container')
if (!element) return
element.style.height = '0vh'
element.classList.remove('show-submenu')
changeStateOfSite(false)
navigate('/')
}}"
>
<button class="img-logo-container"><img src="media/logo.png" alt="logo" /></button>
<p class="logo-text">Wasserski-Erfurt</p>
<button class="img-logo-container"><img src="/media/logo.svg" alt="logo" /></button>
<div class="logo-text">
<p id="upper">ALL KIDS</p>
<p id="lower">SO GÜNSTIG WIE NACHHALTIG</p>
</div>
</button>
<ul class="menuitem-container">
{#if $navigation?.elemente}
{#each $navigation.elemente as site, i (i)}
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<li
class="menu-item"
on:mousedown="{() => {
if (site.endpoint) {
let element = document.getElementById('submenu-container')
element.style.height = '0vh'
element.classList.remove('show-submenu')
changeStateOfSite(false)
navigate(`${$sites[site.seite].path}`)
if (element) {
element.style.height = '0vh'
element.classList.remove('show-submenu')
changeStateOfSite(false)
navigate(`${$sites[site.seite || ''].path}`)
}
}
}}"
on:mouseenter|stopPropagation="{(e) => {
@@ -86,8 +98,10 @@
let elements = document.getElementsByClassName('select-menu')
Array.from(elements).forEach((e) => e.classList.remove('select-menu'))
let element = document.getElementById('submenu-container')
element.style.height = '0vh'
element.classList.remove('show-submenu')
if (element) {
element.style.height = '0vh'
element.classList.remove('show-submenu')
}
changeStateOfSite(false)
}, 500)
}
@@ -103,6 +117,7 @@
</ul>
</ul>
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<button
class="submenu-container"
id="submenu-container"
@@ -117,6 +132,7 @@
<div class="inner-container">
{#each $navigation?.elemente as submenu, i (i * 10)}
{#if !submenu?.endpoint}
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<button
on:mouseover|stopPropagation
class="innersubmenu-container"
@@ -133,16 +149,17 @@
/>
</div>
<ul class="sub-menu">
{#each submenu?.elemente as submenu_point, i (i)}
{#each submenu?.elemente || [] as submenu_point, i (i)}
<li>
<button
class="submenu-item"
on:click="{() => {
let element = document.getElementById('submenu-container')
if (!element) return
element.style.height = '0vh'
element.classList.remove('show-submenu')
changeStateOfSite(false)
navigate(`${$sites[submenu_point.seite]?.path}`)
navigate(`${$sites[submenu_point.seite || '']?.path}`)
}}">{submenu_point?.name}</button
>
</li>
@@ -180,6 +197,18 @@
display: flex;
align-items: center;
.logo-text {
p {
white-space: nowrap;
text-align: left;
}
& > #upper {
font-family: "Orbitron" !important;
font-size: 30px;
font-weight: 700;
}
& > #lower {
font-size: 13px;
}
font-weight: bold;
font-size: 1.2rem;
padding-left: 10px;
@@ -214,11 +243,11 @@
align-items: center;
cursor: pointer;
&:hover {
background-color: @hover-color;
background-color: var(--hover-color);
}
}
.select-menu {
background-color: @hover-color;
background-color: var(--hover-color);
}
}
}
@@ -229,7 +258,7 @@
overflow: hidden;
width: 100vw;
z-index: 2000;
background-color: rgba(0, 0, 0, 0.854);
background-color: var(--opposite-bg-color-80);
opacity: 0;
.inner-container {
width: 100%;
@@ -242,7 +271,7 @@
opacity: 0;
position: absolute;
visibility: hidden;
background-color: rgb(255, 255, 255);
background-color: var(--background-color);
display: flex;
justify-content: center;
.submenu-most-inner-container {
@@ -266,7 +295,7 @@
width: 100%;
text-align: start;
&:hover {
border-bottom: 1px solid rgba(24, 24, 24, 0.795);
border-bottom: 1px solid var(--opposite-bg-color-80);
}
button {
padding: 10px 0px;

View File

@@ -6,7 +6,7 @@
let images: HTMLImageElement[] = []
function changeStateOfSite(menuOn: boolean) {
let element = document.getElementById("menu")
let element = document.getElementById("menu") as HTMLElement
element.classList.toggle("show-menu")
let body = document.body
if (menuOn) {
@@ -26,7 +26,7 @@
}
}
function imageSlide(images) {
function imageSlide(images: HTMLImageElement[]) {
console.log(images)
let currentImage = 0
images[0].classList.add("show-img")
@@ -39,12 +39,15 @@
return () => clearInterval(interval)
}
function pushImages(node) {
function pushImages(node: HTMLImageElement) {
images[0] = node
}
$: {
if (images.length != 0) imageSlide(document.getElementsByClassName("img-menu"))
const images = Array.from(document.getElementsByClassName("img-menu")) as HTMLImageElement[]
if (images.length !== 0) {
imageSlide(images)
}
}
</script>
@@ -54,18 +57,19 @@
class="logo-container"
on:click="{() => {
navigate('/')
let element = document.getElementById('menu')
changeStateOfSite(element.classList.contains('show-menu'))
}}"
>
<button class="img-logo-container"><img src="media/logo.png" alt="logo" /></button>
<p class="logo-text">Wasserski-Erfurt</p>
<button class="img-logo-container"><img src="/media/logo.svg" alt="logo" /></button>
<div class="logo-text">
<p id="upper">ALL KIDS</p>
<p id="lower">SO GÜNSTIG WIE NACHHALTIG</p>
</div>
</button>
<button
class="button-three"
on:click="{(e) => {
let element = document.getElementById('menu')
changeStateOfSite(element.classList.contains('show-menu'))
if (element) changeStateOfSite(element.classList.contains('show-menu'))
}}"
aria-controls="primary-navigation"
aria-expanded="false"
@@ -87,22 +91,27 @@
<div class="inner-container">
<div class="higher-absolute">
{#each $navigation.elemente as link, i (i)}
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<li
class="menu"
on:mousedown|stopPropagation="{(e) => {
if (link.endpoint) {
navigate(`${$sites[link.seite]?.path}`)
navigate(`${$sites[link.seite ?? '']?.path}`)
let element = document.getElementById('menu')
changeStateOfSite(element.classList.contains('show-menu'))
if (element) changeStateOfSite(element.classList.contains('show-menu'))
return
}
let element = e.currentTarget
element.classList.toggle('active')
let chevronContainer = document.getElementById('chevron-' + i)
chevronContainer.src =
chevronContainer.src.split('/')?.pop() == 'chevron-down.png'
? 'media/chevron-up.png'
: 'media/chevron-down.png'
if (element) {
element.classList.toggle('active')
let chevronContainer = document.getElementById('chevron-' + i)
if (chevronContainer)
// @ts-ignore
chevronContainer.src = // @ts-ignore
chevronContainer.src.split('/')?.pop() == 'chevron-down.png'
? 'media/chevron-up.png'
: 'media/chevron-down.png'
}
}}"
>
<div class="menu-point">
@@ -114,13 +123,14 @@
</div>
{#if !link?.endpoint}
<ul class="submenu">
{#each link.elemente as submenu, i (i)}
{#each link.elemente ?? [] as submenu, i (i)}
<li>
<button
on:mousedown="{(e) => {
navigate(`${$sites[submenu.seite]?.path}`)
navigate(`${$sites[submenu.seite ?? '']?.path}`)
let element = document.getElementById('menu')
changeStateOfSite(element.classList.contains('show-menu'))
if (element)
changeStateOfSite(element.classList.contains('show-menu'))
}}">{submenu.name}</button
>
</li>
@@ -131,20 +141,7 @@
{/each}
<button class="socials">
<a target="_blank" href="https://www.instagram.com/wasserski_erfurt/">
<svg
width="36"
height="36"
viewBox="0 0 36 36"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M11.7 3h12.6c4.8 0 8.7 3.9 8.7 8.7v12.6a8.7 8.7 0 0 1-8.7 8.7H11.7C6.9 33 3 29.1 3 24.3V11.7A8.7 8.7 0 0 1 11.7 3zm-.3 3A5.4 5.4 0 0 0 6 11.4v13.2c0 2.985 2.415 5.4 5.4 5.4h13.2a5.4 5.4 0 0 0 5.4-5.4V11.4C30 8.415 27.585 6 24.6 6H11.4zm14.475 2.25a1.875 1.875 0 1 1 0 3.75 1.875 1.875 0 0 1 0-3.75zM18 10.5a7.5 7.5 0 1 1 0 15 7.5 7.5 0 0 1 0-15zm0 3a4.5 4.5 0 1 0 0 9 4.5 4.5 0 0 0 0-9z"
fill="#fff"></path>
</svg>
</a>
<a target="_blank" href="https://www.facebook.com/wasserskierfurt/">
<a target="_blank" href="https://www.facebook.com/allkids.erfurt/">
<svg
width="36"
height="36"
@@ -200,7 +197,8 @@
position: relative;
width: 100%;
height: 100vh;
background-color: white;
background-color: var(--background-color);
ul {
.header {
padding: 0px min(4.5vw, 100px);
@@ -209,7 +207,7 @@
justify-content: space-between;
height: 105px;
.button-three {
--button-color: #333;
--button-color: var(--normal-font-color);
overflow: hidden;
background: transparent;
}
@@ -234,14 +232,25 @@
}
.logo-container {
height: 50px;
height: 38px;
display: flex;
align-items: center;
.logo-text {
p {
white-space: nowrap;
text-align: left;
}
& > #upper {
font-family: "Orbitron" !important;
font-size: 24px;
font-weight: 700;
}
& > #lower {
font-size: 10px;
}
font-weight: bold;
font-size: 1.2rem;
padding-left: 10px;
color: #333;
}
.img-logo-container {
height: 100%;
@@ -282,7 +291,7 @@
}
}
.menu-container {
background-color: white;
background-color: var(--background-color);
position: absolute;
z-index: 2000;
opacity: 0;
@@ -304,18 +313,18 @@
width: 100%;
left: 0px;
padding: 0px min(4.5vw, 100px);
background-color: white;
background-color: var(--background-color);
border-radius: 0px 0px 10px 10px;
}
.socials {
width: 100%;
background-color: @link-font-color;
background-color: var(--link-font-color);
height: 50px;
border-radius: 20px;
color: white;
color: var(--background-color);
}
.active {
background-color: rgba(128, 128, 128, 0.153) !important;
background-color: var(--normal-font-color-12) !important;
.submenu {
visibility: visible;
max-height: 250px;

View File

@@ -0,0 +1,240 @@
<script lang="ts">
import { sites } from "../../stores"
import { register } from "swiper/element/bundle"
import { onMount } from "svelte"
import { navigate } from "svelte-routing"
let teasers = Object.values($sites)?.map((page) => ({ teaser: page.teaser, path: page.path }))
register(false)
let swiper: any
function handleMouseOver() {}
function handleMouseOut() {}
onMount(async () => {
if (swiper !== undefined) {
const response = await fetch("/dist/index.css")
const cssText = await response.text()
const params = {
injectStyles: [cssText],
}
Object.assign(swiper, params)
console.log(swiper.getElementsByClassName("swiper-button-prev"), "test", swiper)
swiper.initialize()
// Add the 'active' class to the h1 of the first slide
const firstSlideH1 = document.querySelector(".swiper-slide-active .titles h1")
if (firstSlideH1) {
firstSlideH1.classList.add("active")
}
}
})
function handleSlideChange() {
document.querySelectorAll(".titles h1").forEach((h1) => {
h1.classList.remove("active")
})
setTimeout(() => {
const activeSlideUnderline = document.querySelector(".swiper-slide-active .titles h1")
if (activeSlideUnderline) {
activeSlideUnderline.classList.add("active")
}
}, 600)
}
let teaser = teasers[0]
</script>
{#if teaser}
<div class="container" id="HP">
<!-- svelte-ignore a11y-no-static-element-interactions -->
<swiper-container
bind:this="{swiper}"
slides-per-view="1"
loop="{true}"
direction="horizontal"
effect="slide"
navigation="{true}"
init="{false}"
autoplay="{{
delay: 4000, // 5000ms = 5s
pauseOnMouseEnter: true,
}}"
speed="600"
on:focus
on:blur
on:slidechange="{() => handleSlideChange()}"
on:mouseenter="{() => handleMouseOver()}"
on:mouseleave="{() => handleMouseOut()}"
class="relative"
>
{#each teasers as teaser}
{#if teaser?.teaser?.showTeaser}
<swiper-slide class="relative">
<div class="inner-container">
<div class="titles">
<h2>{teaser?.teaser?.subTitle}</h2>
<h1>
{teaser?.teaser?.teaserTitle}
<div class="underline"></div>
</h1>
</div>
<div class="description">
<div class="placeholder"></div>
<div
style=" display: flex;
flex-direction: column;
align-items: start;
gap: 20px;"
>
<div style="text-align: left;">
<p>{@html teaser?.teaser?.teaserDescription}</p>
</div>
<button
on:click="{() => navigate(teaser.path)}"
style="
font-weight: bold;
color: var(--link-font-color);
width: fit-content;
border-top: 3px solid var(--link-font-color);
margin-top: 3rem;
">MEHR</button
>
</div>
<div class="placeholder"></div>
</div>
</div>
</swiper-slide>
{/if}
{/each}
</swiper-container>
</div>
{/if}
<style lang="less" global>
@import "../../assets/css/variables.less";
@import "swiper/swiper-bundle.min.css";
@import "swiper/modules/effect-fade/effect-fade";
@import "swiper/modules/navigation/navigation";
@import "swiper/modules/pagination/pagination";
@import "../../assets/css/SwiperStylesHP.less";
.container#HP {
padding: 20px 0px 150px 0px;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
swiper-container {
max-width: 90vw;
width: 1800px;
}
.inner-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
gap: 20px;
@media @tablet {
align-items: center;
gap: initial;
}
width: 100%;
height: fit-content;
.titles {
padding: 0 5%;
font-weight: 500;
h1 {
font-size: 2rem;
padding: 10px 0px 0px 0px;
@media @tablet {
padding: 20px 0px;
}
margin: 10px 0px 20px 0px;
line-height: 1;
font-weight: 500;
position: relative;
}
h2 {
font-size: 0.9rem !important;
@media @tablet {
font-size: 1.6rem !important;
}
line-height: 1;
font-weight: 500;
}
}
.description {
display: flex;
flex-direction: row;
& > div {
flex: 0 0 5%;
min-width: 0px;
}
& > div:nth-child(2) {
flex: 0 0 90%;
min-width: 0px;
}
}
@media @tablet {
.titles {
font-weight: 500;
h1 {
font-size: 3.5rem;
padding: 20px 20px;
margin: 20px 0px 40px 0px;
font-weight: 500;
}
h2 {
font-size: 1.3rem;
}
font-weight: 500;
}
.description {
display: flex;
flex-direction: row;
& > div {
flex: 0 0 25%;
min-width: 0px;
}
& > div:nth-child(2) {
flex: 0 0 50%;
min-width: 0px;
}
}
}
@media @desktop {
.titles {
font-weight: 500;
h1 {
font-size: 5rem;
padding: 20px 0px;
margin: 20px 0px 40px 0px;
font-weight: 500;
}
h2 {
font-size: 1.6rem;
font-weight: 500;
}
}
.description {
display: flex;
flex-direction: row;
& > div {
flex: 0 0 33.33%;
min-width: 0px;
}
}
}
}
}
</style>

View File

@@ -4,7 +4,7 @@
let isExpanded = false
let currentIndex = 0
let interval
let interval: NodeJS.Timer
let img: HTMLImageElement
function toggleBanner() {
@@ -74,7 +74,7 @@
.toggle {
position: absolute;
left: 50%;
background-color: @banner-color;
background-color: var(--banner-color);
transform: translate(-50%, -100%);
border-radius: 10px;
}
@@ -107,7 +107,7 @@
bottom: 0;
left: 0;
right: 0;
background-color: @banner-color;
background-color: var(--banner-color);
cursor: pointer;
transition: width 0.5s ease-in-out, height 0.5s ease-in-out;
img {
@@ -115,8 +115,6 @@
}
}
.banner.expanded {
}
.banner-container {
width: 100%;
height: 100%;
@@ -124,13 +122,13 @@
display: flex;
justify-content: space-between;
position: relative;
color: white;
color: var(--background-color);
.toggle {
padding: 10px;
}
.banner-text {
color: white;
color: var(--background-color);
transition: opacity 0.3s ease-in-out;
pointer-events: none;
opacity: 0;

View File

@@ -0,0 +1,43 @@
<script lang="ts">
export let col: Column
import inView from "../../functions/observer"
let visible = false
import { fade } from "svelte/transition"
</script>
<div class="boxList">
{#each col.boxList.boxes as name, i}
{#key visible}
<div
class="box"
use:inView="{{ threshold: 0 }}"
on:enter="{() => {
visible = true
}}"
in:fade="{{ duration: 500, delay: 100 + 80 * (i + 1) }}"
>
{name.name}
</div>{/key}
{/each}
</div>
<style lang="less">
@import "../../assets/css/variables.less";
.boxList {
display: flex;
flex-wrap: wrap;
gap: 20px;
.box {
padding: 5px 10px;
background-color: var(--opposite-bg-color-80);
color: var(--background-color);
font-weight: bold;
cursor: pointer;
&:hover {
background-color: var(--hover-color);
color: var(--opposite-bg-color-80);
}
}
}
</style>

View File

@@ -1,10 +1,12 @@
<script lang="ts">
import FormLabelNumberBlock from "./formLabelNumberBlock.svelte"
import type { Writable } from "svelte/store"
export let formRow: FormRow
export let index: number
export let formValues
function getSortedFields(column: FormColumn) {
export let formValues: Writable<FormValues>
/* function getSortedFields(column: FormColumn) {
const fields = [
...(column.text.length ? [{ text: column.text, type: "text", order: column.textfieldOrder ?? 3 }] : []),
...(column.showTimes ? [{ type: "times", order: column.timesfieldOrder ?? 3, times: column.times }] : []),
@@ -13,11 +15,11 @@
: []),
]
return fields.sort((a, b) => a.order - b.order)
}
}*/
//formRow.columns = formRow.columns.map((e) => getSortedFields(e))
function removeInvalid(e) {
let element = e.currentTarget
element.classList.remove("invalid")
function removeInvalid(e: Event) {
let element = e.currentTarget as HTMLElement
if (element) element.classList.remove("invalid")
}
</script>
@@ -46,7 +48,7 @@
on:change="{removeInvalid}"
>
<option value="" disabled selected>Bitte Uhrzeit wählen</option>
{#each column?.times as time}
{#each column?.times || [] as time}
<option value="{time?.timeFrom}-{time?.timeTo}">
{time?.timeFrom} - {time?.timeTo}
</option>
@@ -112,7 +114,7 @@
</label>
{/if}
{#each column.text as textField, textFieldIndex}
{#each column.text || [] as textField, textFieldIndex}
{#if textField?.textArea}
<label bind:this="{$formValues[`textarea_Nachricht_label`]}">
<textarea

View File

@@ -1,10 +1,11 @@
<script lang="ts">
export let column
export let formValues
export let rowIndex
let blockContainer
import type { Writable } from "svelte/store"
export let column: FormColumn
export let formValues: Writable<FormValues>
export let rowIndex: number
let blockContainer: HTMLDivElement
$formValues["blockGroups"] = new Set(column.labelNumber.map((e) => e.group))
console.log($formValues["blockGroups"])
</script>
<div class="blockContainer" bind:this="{blockContainer}">

View File

@@ -1,15 +1,16 @@
<script lang="ts">
import FormLabelNumberBlock from "./formLabelNumberBlock.svelte"
import type { Writable } from "svelte/store"
export let formRow: FormRow
export let formValues
export let index
function removeInvalid(e) {
let element = e.currentTarget
element.classList.remove("invalid")
export let formValues: Writable<FormValues>
export let index: number
function removeInvalid(e: Event) {
let element = e.currentTarget as HTMLElement
if (element) element.classList.remove("invalid")
}
function getPosition(column, pos, i = 0) {
function getPosition(column: FormColumn, pos: number, i = 0) {
let position = 0
if (pos == 0) return
if (column.showLabelNumber) position++
@@ -53,7 +54,7 @@
on:change="{removeInvalid}"
>
<option value="" disabled selected>Bitte Uhrzeit wählen</option>
{#each column?.times as time}
{#each column?.times ?? [] as time}
<option value="{time?.timeFrom}-{time?.timeTo}">
{time?.timeFrom} - {time?.timeTo}
</option>
@@ -126,7 +127,7 @@
</div>
{/if}
{#each column.text as textField, textFieldIndex}
{#each column.text ?? [] as textField, textFieldIndex}
<div class="column-{columnIndex} position-{getPosition(column, 5 + textFieldIndex, textFieldIndex)}">
{#if textField?.textArea}
<label bind:this="{$formValues[`textarea_Nachricht_label`]}">

View File

@@ -2,7 +2,7 @@
import { navigate } from "svelte-routing"
import { fly } from "svelte/transition"
export let col: Column
export let siteId
export let siteId: string
import { apiBaseURL } from "../../../config"
import inView from "../../functions/observer"
let visible = false
@@ -19,7 +19,7 @@
}}"
>
{#key visible}
{#each col.iconBoard as icon, i (i)}
{#each col.iconBoard ?? [] as icon, i (i)}
<div
class="img-container"
id="{'img-container' + i}"
@@ -67,7 +67,7 @@
min-width: 25%;
.subText {
text-align: center;
color: @heading-font-color;
color: var(--heading-font-color);
}
@media @mobile {
width: 50%;
@@ -77,17 +77,5 @@
}
}
}
@media @tablet {
main {
margin-top: 300px !important;
}
.background-container {
margin-top: -180px !important;
}
.title {
font-size: 3rem !important;
}
}
}
</style>

View File

@@ -0,0 +1,75 @@
<script lang="ts">
import { apiBaseURL } from "../../../config"
import { fly } from "svelte/transition"
import inView from "../../functions/observer"
let visible = false
let node
export let col: Column
export let pageId: string
export let i: number
</script>
{#key visible}
<div
class="infoBoard"
bind:this="{node}"
use:inView="{{ threshold: 0 }}"
on:enter="{() => {
visible = true
}}"
in:fly="{{ duration: 600, delay: 100 + 100 * (i + 1), x: 300 + i * 200, opacity: 0 }}"
>
<div class="header">
<div class="icon">
<svg
id="mySvgObject{i}"
fill="var(--link-font-color)"
data-src="{`${apiBaseURL}content/${pageId}/${col.iconInfoBoard.icon?.src}`}"></svg>
</div>
<div class="title">
{col.iconInfoBoard.title}
<div></div>
</div>
</div>
<div class="content">
{@html col.iconInfoBoard.text}
</div>
</div>
{/key}
<style lang="less">
@import "../../assets/css/variables.less";
.infoBoard {
display: flex;
flex-direction: column;
padding: 15px;
gap: 40px;
.header {
display: flex;
align-items: center;
gap: 20px;
.icon {
width: 64px;
height: 64px;
svg {
width: 100%;
height: 100%;
object-fit: contain;
}
}
.title {
font-size: 1.5rem;
display: flex;
flex-direction: column;
color: var(--link-font-color);
div {
border-bottom: 1px solid var(--normal-font-color);
width: 50px;
}
}
}
.content {
text-align: left;
}
}
</style>

View File

@@ -1,14 +1,13 @@
<script lang="ts">
import { onMount } from "svelte"
import { register } from "swiper/element/bundle"
import Pagebuilder from "./Pagebuilder.svelte"
import { apiBaseURL } from "../../../config"
export let siteId
export let siteImages
export let siteId: string
export let siteImages: ImageSlider[]
register(false)
let swiper
let swiper: any
onMount(async () => {
if (swiper !== undefined) {
@@ -27,7 +26,7 @@
</script>
{#if siteImages.length > 1}
<div class="flex">
<div class="flex images">
<swiper-container
bind:this="{swiper}"
slides-per-view="1"
@@ -42,7 +41,7 @@
class="relative"
>
{#each siteImages as image, i (i)}
<swiper-slide class="relative">
<swiper-slide class="relative" id="image">
<div class="image-container">
<img
src="{`${apiBaseURL}content/${siteId}/${image.image?.src}?filter=${
@@ -71,11 +70,13 @@
@import "swiper/modules/pagination/pagination.less";
@import "../../assets/css/variables.less";
@import "../../assets/css/swiperStyles.less";
swiper-container {
height: auto;
width: 100%;
max-width: 100vw;
}
swiper-slide {
swiper-slide#image {
width: 100% !important;
}
.flex {

View File

@@ -1,12 +1,12 @@
<script lang="ts">
import { navigate } from "svelte-routing"
import { fly } from "svelte/transition"
export let col: Column
export let siteId
export let i
export let siteId: string
export let i: number
import { apiBaseURL } from "../../../config"
import inView from "../../functions/observer"
let visible
let visible = false
let node
</script>
@@ -36,9 +36,11 @@
<div class="links">
{#if col?.links}
{#each col?.links as link}
<button on:click="{() => navigate(link?.site)}">
<img src="media/arrow-right.svg" alt="arrow" />{link?.name}
</button>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11H4z"
fill="var(--link-font-color)"></path>
</svg>
{/each}
{/if}
</div>
@@ -70,8 +72,7 @@
font-weight: 700;
padding-bottom: 1.2rem;
}
.description-container {
}
.links {
margin-top: 25px;
img {
@@ -81,7 +82,7 @@
button {
display: flex;
align-items: center;
color: @link-font-color;
color: var(--link-font-color);
font-weight: 600;
margin: 10px 0px;
}

View File

@@ -1,7 +1,7 @@
<script lang="ts">
import { fly } from "svelte/transition"
export let col: Column
export let siteId
export let siteId: string
import { apiBaseURL } from "../../../config"
</script>
@@ -15,7 +15,7 @@
/>
</div>
<div class="inscription" in:fly="{{ duration: 1000, delay: 500, y: 50, opacity: 0 }}">
{col.inscription}
{col.inscription || ""}
</div>
</div>
@@ -44,7 +44,7 @@
margin-right: 35px;
font-size: 1.7rem;
font-weight: 700;
color: white;
color: var(--heading-font-color);
}
@media @tablet {
.inscription {

View File

@@ -1,7 +1,6 @@
<script lang="ts">
export let row: Row
export let rows: Row[]
import { apiBaseURL } from "../../../config"
import IconBoard from "./iconBoard.svelte"
import Image from "./image.svelte"
import InfoBoard from "./infoBoard.svelte"
@@ -13,24 +12,23 @@
import { writable } from "svelte/store"
import { validateFields } from "../../functions/validateFields"
import { sendForm } from "../../functions/sendForm"
import VideoSwitch from "../videoSwitch.svelte"
import GoogleMaps from "../googleMaps.svelte"
import Video from "./video.svelte"
import { navigate } from "svelte-routing"
import { onMount } from "svelte"
export let siteId
export let rowNr
import IconInfoBoard from "./iconInfoBoard.svelte"
import Boxlist from "./boxlist.svelte"
import ProductPreview from "./productPreview.svelte"
export let siteId: string
export let rowNr: number
let formSend = false
let formValues = writable({})
function getRowClass(row) {
let formValues = writable<FormValues>({})
function getRowClass(row: Row) {
if (row.maxWidth || row.column.some((col) => col.iconBackgroundImage)) return "max-width"
return row.column.some((col) => col.contentType === "mainPicture" || col.contentType == "video")
? "max-width"
: "small-max-width"
return row.column.some((col) => col.contentType === "mainPicture") ? "max-width" : "small-max-width"
}
function submitForm(e) {
function submitForm() {
const values = Object.entries($formValues).map((entry) => {
return [
entry[0],
@@ -41,114 +39,75 @@
})
const fields = values.filter((entry) => !entry[0].includes("label"))
console.log(fields)
const validation = validateFields([...fields])
if (validation.length) {
validation.forEach((error) => {
// @ts-ignore
if (error[0].includes("block")) {
// @ts-ignore
error[1]()
} else {
// @ts-ignore
$formValues[error[1]].classList.add("invalid")
const label = $formValues[`${error[1]}_label`]
const errorElement = document.createElement("div")
errorElement.className = "error-message"
errorElement.textContent = error[0]
errorElement.textContent = error[0] as string
label?.appendChild(errorElement)
}
})
} else {
const formObj = {}
const formObj: any = {}
fields.forEach((entry) => {
if (Array.isArray(entry[1]) && entry[1].length == 4) {
// @ts-ignore
if (entry[1][0]) formObj[entry[0]] = entry[1]
} else {
if (!entry[1][0] && !entry[1][1]) return
// @ts-ignore
formObj[entry[0]] = entry[1][0]
}
})
console.log(fields, formObj)
let form
let form: any
row.column.forEach((col) => {
if (col.contentType == "form") form = col
})
formObj["formRows"] = form.formRows.map((r) => r.rowName)
if (!form) return
formObj["formRows"] = form.formRows.map((r: FormRow) => r.rowName)
formObj["formTitle"] = form.formEmailTitle
formSend = true
const hny = document.getElementById("hny")
formObj["honey"] = hny.checked
const hny = document.getElementById("hny") as HTMLInputElement
if (hny) formObj["honey"] = hny.checked
sendForm(formObj)
}
}
let videoElement
onMount(() => {
if (videoElement) {
var source = document.createElement("source")
if (window.innerWidth <= 767) {
source.src = "media/wasser_mobile.webm"
} else {
source.src = "media/wasser_desktop.webm"
}
videoElement.appendChild(source)
videoElement.load()
}
const handleResize = () => {
innerWidth = window.innerWidth
if (
(window.innerWidth >= 768 && innerWidthStore < 768) ||
(window.innerWidth < 768 && innerWidthStore >= 768)
) {
innerWidthStore = window.innerWidth
window.location.reload()
}
}
window.addEventListener("resize", handleResize)
// Cleanup function
return () => {
window.removeEventListener("resize", handleResize)
}
})
let innerWidth = window.innerWidth
let innerWidthStore = window.innerWidth
</script>
<main class="row" name="{row.title}" class:max-width="{getRowClass(row) === 'max-width'}" id="{`RowNr` + rowNr}">
{#if row?.iconBackgroundImage}
<div class="virtual-container">
<div class="wavebackground-container">
{#if row?.iconBackgroundTitle} <div class="title">Highlights des Sees</div>{/if}
<video class="video-background" autoplay loop muted playsinline bind:this="{videoElement}"> </video>
</div>
</div>
{#if row.title}
<h3 class="row-title" class:no-margin="{rowNr == 0}">{row?.title || ""}</h3>
{/if}
{#if row.iconBackgroundImage}
<div class="wave-placeholder"></div>
{/if}
{#if row.title || row.iconBackgroundImage}
<h3 class="row-title" class:no-margin="{rowNr == 0 || row.iconBackgroundImage}">{row?.title || ""}</h3>
{/if}
<div class:no-gap="{row.noGap}">
{#each row.column as col, i}
<div class:no-gap="{row.noGap}" class:wrapAfterTwo="{row.column.length >= 4}">
{#each row.column || [] as col, i}
{#if col.contentType == "mainPicture"}
<MainPicture col="{col}" siteId="{siteId}" />
{:else if col.contentType == "text"}
<TextContent rows="{rows}" col="{col}" />
{:else if col.contentType == "infoBoard"}
<InfoBoard siteId="{siteId}" col="{col}" i="{i}" />
{:else if col.contentType == "iconInfoBoard"}
<IconInfoBoard pageId="{siteId}" col="{col}" i="{i}" />
{:else if col.contentType == "boxlist"}
<Boxlist col="{col}" />
{:else if col.contentType == "iconBoard"}
<IconBoard col="{col}" siteId="{siteId}" i="{i}" />
<IconBoard col="{col}" siteId="{siteId}" />
{:else if col.contentType == "image"}
<Image siteImages="{col.imageSlider}" siteId="{siteId}" />
{:else if col.contentType == "table"}
<Table col="{col}" rows="{rows}" />
{:else if col.contentType == "videos"}
<VideoSwitch col="{col}" siteId="{siteId}" />
{:else if col.contentType == "video"}
<Video col="{col}" siteId="{siteId}" />
{:else if col.contentType == "productPreview"}
<ProductPreview col="{col}" siteId="{siteId}" />
{:else if col.contentType == "googleMaps"}{#if col.showGoogleMaps}
<GoogleMaps />
{/if}
@@ -163,10 +122,10 @@
class="form-rows"
on:submit="{(e) => {
e.preventDefault()
submitForm(e)
submitForm()
}}"
>
{#each col.formRows as formRow, i}
{#each col.formRows ?? [] as formRow, i}
{#if innerWidth < 768}
<MobileForm formRow="{formRow}" formValues="{formValues}" index="{i}" />
{:else}
@@ -228,67 +187,10 @@
margin: 5px 0px;
box-shadow: 0 0 25px 10px rgba(0, 0, 0, 0.05);
}
.virtual-container {
display: flex;
padding-top: 90px;
max-width: @body-small-maxwidth;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
width: 100%;
.wavebackground-container {
position: absolute;
overflow: hidden;
display: flex;
justify-content: center;
width: 100vw;
left: 0px;
height: 450px;
z-index: -1;
.video-background {
position: absolute;
width: 100%;
height: 100%;
object-fit: cover;
-webkit-mask-image: url("../../../../media/welle.svg");
mask-image: url("../../../../media/welle.svg");
-webkit-mask-size: 30px;
mask-size: 30px;
-webkit-mask-repeat: repeat-x;
mask-repeat: repeat-x;
z-index: -1;
}
@media @mobile {
.title {
margin-top: 40px;
}
}
@media @tablet {
.title {
margin-top: 75px;
}
}
.title {
font-size: 2rem;
color: white;
font-weight: bold;
}
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(to top, rgb(255, 255, 255), rgba(255, 255, 255, 0.144));
z-index: 10;
}
}
}
.success-message {
h1 {
color: @banner-color;
color: var(--banner-color);
font-size: 36px;
margin-top: 50px;
}
@@ -314,15 +216,12 @@
border-color: red !important;
}
li {
}
.row-title {
font-size: 1.6rem;
font-weight: bold;
line-height: normal;
width: 100%;
color: @heading-font-color;
color: var(--heading-font-color);
@media @mobile {
margin: 3.2rem 1.5vw 1.6rem;
}
@@ -361,6 +260,7 @@
input[type="number"] {
-moz-appearance: textfield;
appearance: textfield;
}
ul {
@@ -374,7 +274,7 @@
li::before {
content: ""; /* Add an empty content */
background-image: url("../../../../media/arrow-right.svg"); /* Replace this with the path to your SVG file */
background-image: url("../../../../media/arrow-right.svg");
background-size: contain;
background-repeat: no-repeat;
position: absolute;
@@ -427,13 +327,13 @@
}
.submit-request {
flex: 1;
box-shadow: 0 0 25px 10px rgba(0, 0, 0, 0.05);
box-shadow: 0 0 25px 10px var(--opposite-bg-color-5);
width: 100%;
display: flex;
align-items: center;
justify-content: start;
background-color: @heading-font-color;
color: white;
background-color: var(--heading-font-color);
color: var(--background-color);
padding: 10px 20px;
}
}
@@ -491,7 +391,7 @@
p {
margin-bottom: 0.5rem;
color: #777;
color: var(--hover-color);
}
input,
@@ -500,10 +400,10 @@
.data-protection {
padding: 10px 20px;
border: 0px solid black;
border-bottom: 3px solid @heading-font-color;
border-bottom: 3px solid var(--heading-font-color);
outline: 0px solid black;
background-color: white;
background-color: var(--background-color);
resize: none;
}
@@ -525,12 +425,12 @@
select {
padding: 10px 20px;
border: 0;
border-bottom: 3px solid @heading-font-color;
border-bottom: 3px solid var(--heading-font-color);
outline: none;
}
select:focus {
border-bottom-color: @heading-font-color;
border-bottom-color: var(--heading-font-color);
}
#time-select {
@@ -542,15 +442,13 @@
option {
padding: 10px 20px;
background-color: white;
background-color: var(--background-color);
}
}
@media @mobile {
.date {
width: 100vw !important;
}
.form-cols {
}
}
@media @tablet {
.date {
@@ -585,6 +483,10 @@
& > div {
gap: 40px;
}
& > div.wrapAfterTwo {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
}
@media @desktop {
.no-gap {
@@ -593,7 +495,9 @@
.row-title {
font-size: 2.5rem !important;
}
& > div {
& > div,
& > div.wrapAfterTwo {
display: flex;
flex-direction: row;
align-items: start;
justify-content: center;

View File

@@ -0,0 +1,120 @@
<script lang="ts">
export let col: Column
export let siteId: string
import { register } from "swiper/element/bundle"
import { apiBaseURL } from "../../../config"
import { onMount } from "svelte"
register(false)
let swiper: any
console.log("TST RENDERED")
onMount(async () => {
if (swiper) {
const response = await fetch("/dist/index.css")
const cssText = await response.text()
const params = {
injectStyles: [cssText],
}
if (swiper) {
Object.assign(swiper, params)
swiper.initialize()
}
}
})
</script>
<main id="products">
<swiper-container
bind:this="{swiper}"
slides-per-view="3"
loop="{true}"
direction="horizontal"
effect="coverflow"
init="{false}"
speed="400"
class="relative"
grab-cursor="{true}"
scrollbar-hide="false"
on:focus
on:blur
autoplay="{{
delay: 1000, // 5000ms = 5s
pauseOnMouseEnter: true,
}}"
>
{#each col.productPreview as product}
<swiper-slide class="relative" id="product">
<div class="product">
<div class="img-container">
<img
src="{`${apiBaseURL}content/${siteId}/${product.image?.src}?filter=${
window.innerWidth > 500 ? 'xl' : 'm'
}`}"
alt="img"
/>
<div class="price-container">
{product?.price}
</div>
</div>
<div class="title-container">
{@html product?.title}
</div>
<div class="description-container">
{@html product?.text}
</div>
</div>
</swiper-slide>
{/each}
</swiper-container>
</main>
<style lang="less" global>
@import "../../assets/css/variables.less";
@import "swiper/swiper-bundle.min.css";
@import "swiper/modules/effect-fade/effect-fade";
@import "swiper/modules/navigation/navigation";
@import "swiper/modules/pagination/pagination";
@import "../../assets/css/productSwiper.less";
#products {
flex: 1;
display: flex;
justify-content: center;
max-width: @body-small-maxwidth;
.product {
margin: 0px 35px 40px 35px;
.img-container {
flex: 1;
height: 270px;
background-color: var(--background-color);
@media @tablet {
height: 65vw;
}
@media @desktop {
height: 270px;
}
img {
width: 100%;
height: 100%;
object-fit: contain;
padding: 1rem 0px;
}
position: relative;
.price-container {
position: absolute;
bottom: 1rem;
right: 0px;
font-weight: bold;
background-color: var(--background-color);
padding: 9px;
}
}
.title-container {
font-weight: 700;
padding-bottom: 1.2rem;
}
}
}
</style>

View File

@@ -0,0 +1,66 @@
<script>
import { onMount, onDestroy } from "svelte"
// import { rerender } from "../../store"
let showButton = true
const checkScroll = () => {
// Change the visibility of the button based on the scroll position
showButton = window.pageYOffset < 100
}
const jumpDown = () => {
// Jump down by 100vh
window.scrollTo({ top: window.innerHeight, behavior: "smooth" })
}
onMount(() => {
// Attach scroll event listener when component is mounted
window.addEventListener("scroll", checkScroll)
})
onDestroy(() => {
// Remove scroll event listener when component is destroyed
window.removeEventListener("scroll", checkScroll)
})
let force = true
setInterval(() => {
if (location.pathname != "/") {
force = false
} else force = true
}, 1000)
$: {
/* if ($rerender) {
if (location.pathname != "/") {
force = false
} else force = true
}*/
}
</script>
{#if showButton && force}
<button on:click="{jumpDown}" class="jump-down"
><span> SCROLL </span>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="m22.723 5.473 1.054 1.054L12 18.305.223 6.527l1.054-1.054L12 16.195 22.723 5.473z"
fill="var(--link-font-color)"></path>
</svg>
</button>
{/if}
<style>
.jump-down {
/* Place your styles here */
display: flex;
flex-direction: column;
align-items: center;
position: fixed;
color: var(--link-font-color);
z-index: 100;
gap: 5px;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
}
</style>

View File

@@ -0,0 +1,54 @@
<script>
import { onMount, onDestroy } from "svelte"
let showButton = false
const checkScroll = () => {
// Change the visibility of the button based on the scroll position
showButton = window.pageYOffset > 200
}
const scrollToTop = () => {
// Scroll smoothly to the top
window.scrollTo({ top: 0, behavior: "smooth" })
}
onMount(() => {
// Attach scroll event listener when component is mounted
window.addEventListener("scroll", checkScroll)
})
onDestroy(() => {
// Remove scroll event listener when component is destroyed
window.removeEventListener("scroll", checkScroll)
})
</script>
{#if showButton}
<button on:click="{scrollToTop}" class="arrow-up">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z" fill="var(--background-color)"
></path>
</svg></button
>
{/if}
<style lang="less">
@import "../../assets/css/variables.less";
.arrow-up {
position: fixed;
display: flex;
align-items: center;
justify-content: center;
bottom: 10px;
right: 10px;
height: 2rem;
width: 2rem;
border-radius: 50%;
z-index: 1000;
background-color: var(--link-font-color);
svg {
transform-origin: center;
}
}
</style>

View File

@@ -2,7 +2,7 @@
import inView from "../../functions/observer"
import { fly } from "svelte/transition"
export let rows: Row[]
function scrollToRow(name) {
function scrollToRow(name: string) {
const element = document.getElementsByName(name)[0]
if (element) {
element.scrollIntoView({ behavior: "smooth" })
@@ -27,7 +27,10 @@
class="siteRef"
on:click="{() => scrollToRow(row.title)}"
in:fly="{{ duration: 1000, delay: 40 * i, opacity: 0, y: 150 }}"
><img src="media/arrow-bottom-right.svg" alt="arrow" />{row?.title}</button
><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 6.41 6.41 5 17 15.59V9h2v10H9v-2h6.59L5 6.41z" fill="var(--link-font-color)"></path>
</svg>
{row?.title}</button
>
{/if}
{/each}
@@ -41,11 +44,11 @@
button {
display: flex;
align-items: center;
img {
svg {
transform: scale(1.4);
margin: 0.5rem 0.9rem 0.5rem 0rem;
}
color: @link-font-color;
color: var(--link-font-color);
font-weight: 600;
}
}

View File

@@ -19,7 +19,7 @@
>
<h3>{col?.tableFieldHeading ?? ""}</h3>
{#key visible}
{#each col?.table as table, i (table?.title)}
{#each col?.table ?? [] as table, i (table?.title)}
<div class="table" in:fly="{{ duration: 1000, delay: i * 150, y: 130, opacity: 0 }}">
<div class="tableTitle">{table?.title ?? ""}</div>
@@ -89,7 +89,7 @@
font-size: 2rem;
font-weight: bold;
margin: 0rem 0vw 1.6rem 0vw;
color: @heading-font-color;
color: var(--heading-font-color);
}
h5 {

View File

@@ -2,12 +2,12 @@
import { navigate } from "svelte-routing"
export let site: Site
import Image from "./image.svelte"
export let index
export let index: number
</script>
<main class="teaser">
{#if index % 2 == 0 || window.innerWidth < 1023}
<Image siteId="{site?.id}" siteImages="{site?.teaserImages}" />
<Image siteId="{site?.id}" siteImages="{site?.teaserImages || []}" />
{/if}
<div class="content">
<h3>{site?.teaserTitle}</h3>
@@ -15,7 +15,7 @@
<button on:click="{() => navigate(site.path)}">MEHR</button>
</div>
{#if index % 2 == 1 && window.innerWidth > 1023}
<Image siteId="{site?.id}" siteImages="{site?.teaserImages}" />
<Image siteId="{site?.id}" siteImages="{site?.teaserImages || []}" />
{/if}
</main>
@@ -41,13 +41,13 @@
font-size: 2rem;
font-weight: bold;
margin: 0rem 0 1.6rem 0;
color: @heading-font-color;
color: var(--heading-font-color);
}
button {
font-weight: bold;
color: @link-font-color;
color: var(--link-font-color);
width: fit-content;
border-top: 3px solid @link-font-color;
border-top: 3px solid var(--link-font-color);
margin-top: 3rem;
}
}

View File

@@ -6,7 +6,7 @@
</script>
<div class="text-container">
<h3 class:noMargin={!col.textFieldHeading}>{col.textFieldHeading ?? ""}</h3>
<h3 class:noMargin="{!col.textFieldHeading}">{col.textFieldHeading ?? ""}</h3>
{#if col?.textContent}
<div>
{@html col?.textContent}
@@ -15,11 +15,12 @@
{#if col.siteReference}
<SiteRefs rows="{rows}" />
{/if}
<li style="display: none;"></li>
</div>
<style lang="less">
@import "../../assets/css/variables.less";
.noMargin{
.noMargin {
margin: 0px !important;
}
.text-container {
@@ -30,7 +31,7 @@
font-size: 2rem;
font-weight: bold;
margin: 0rem 0vw 1.6rem 0vw;
color: @heading-font-color;
color: var(--heading-font-color);
}
}
@media @mobile {

View File

@@ -1,163 +0,0 @@
<script lang="ts">
import { apiBaseURL } from "../../../config"
import { navigate } from "svelte-routing"
import { fly } from "svelte/transition"
let container
let videoElement
let videoText
let videoWrapper
let cooldown = false
export let col
export let siteId
</script>
<div id="wrapper" class="video-container" bind:this="{container}">
<div class="video-wrapper video-wrapper-big" bind:this="{videoWrapper}">
<div class="text shown" bind:this="{videoText}">
<h2 in:fly="{{ duration: 1000, delay: 500, y: 50, opacity: 0 }}">{col.titleVideo}</h2>
<p in:fly="{{ duration: 1000, delay: 500, y: 50, opacity: 0 }}">
{col.descriptionVideo}
</p>
</div>
<video
autoplay
class="video"
playsinline
src="{`${apiBaseURL}content/${siteId}/${col.video?.src}`}"
loop
alt="video1"
muted
bind:this="{videoElement}"><track kind="captions" /></video
>
</div>
</div>
<style lang="less">
@import "../../assets/css/variables.less";
#wrapper {
width: 100%;
flex: 2;
}
.video-wrapper {
width: 100%;
display: flex;
max-height: min(700px, 55vh);
overflow: hidden;
position: relative;
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.3);
z-index: 10;
}
@media @mobile {
.hidden {
p,
button {
visibility: hidden !important;
opacity: 0;
height: 0px;
margin-top: 0px !important;
transition: opacity 0s;
}
h2 {
margin-bottom: 0px !important;
transform: translateY(50%);
}
}
.shown {
opacity: 1;
visibility: visible;
}
}
@media @desktop {
.hidden {
h2 {
visibility: hidden;
transition: opacity 0s;
}
}
}
.text {
position: absolute;
z-index: 20;
max-width: 85%;
color: rgb(255, 255, 255);
animation-delay: 500ms;
bottom: 35px;
left: 35px;
@media @mobile {
h2 {
font-size: 2.8rem;
font-weight: bold;
line-height: normal;
margin-bottom: 5px;
}
p {
line-height: normal;
}
button {
border-top: 3px solid white;
font-size: 1.4rem;
font-weight: bold;
color: white;
margin-top: 15px;
}
}
@media @desktop {
max-width: 70%;
h2 {
font-size: 2.7rem;
}
p {
}
button {
font-size: 1.5rem;
}
}
}
}
.video {
width: 100%;
min-height: max(35vh, 400px);
height: 100% !important;
object-fit: cover;
}
@media (max-width: 1023px) {
.video-container {
flex-direction: column;
}
.text {
max-width: 90%;
}
video {
height: 100% !important;
min-height: max(45vh, 60vw) !important;
width: auto !important;
min-width: 100%;
object-fit: cover;
object-position: center;
}
.video-wrapper-small,
.video-wrapper-big {
width: 100%;
}
}
</style>

View File

@@ -1,315 +0,0 @@
<script lang="ts">
import { onMount } from "svelte"
import { apiBaseURL } from "../../config"
import { navigate } from "svelte-routing"
import { temperature } from "../stores"
export let siteId
let container
let videoElements = []
let videoTexts = []
let videoWrappers = []
let cooldown = false
export let col
onMount(() => {
container.style.height = videoElements[0].offsetHeight + "px"
Array.from(videoElements).forEach((e) => {
e.style.height = "100%"
})
videoElements[0].play()
videoElements[1].play()
setTimeout(() => {
videoElements[1].pause()
}, 0)
videoWrappers.forEach((videoWrapper) => {
const video = videoWrapper.querySelector(".video")
let eventFunc = (e) => {
if (cooldown) return
let selected = e.currentTarget
cooldown = true
setTimeout(() => {
cooldown = false
}, 502)
let text = selected.querySelector(".text")
videoWrappers.forEach((vw) => {
if (selected == vw) {
vw.classList.add("video-wrapper-big")
vw.classList.remove("video-wrapper-small")
} else {
vw.classList.add("video-wrapper-small")
vw.classList.remove("video-wrapper-big")
}
vw.querySelector(".video").pause()
})
videoTexts.forEach((vt) => {
if (text == vt) {
setTimeout(() => {
vt.classList.add("shown")
vt.classList.remove("hidden")
}, 500)
} else {
vt.classList.add("hidden")
vt.classList.remove("shown")
}
})
video.play()
}
videoWrapper.addEventListener("mousemove", (e) => eventFunc(e))
videoWrapper.addEventListener("click", (e) => eventFunc(e))
})
})
let innerWidth = window.innerWidth
</script>
<div class="video-top-lvl-container">
<div id="wrapper" class="video-container" bind:this="{container}">
<div class="video-wrapper video-wrapper-big" bind:this="{videoWrappers[0]}">
<div class="text shown" bind:this="{videoTexts[0]}">
<h2>{col.videoSwitch[0]?.title}</h2>
<p>
{col.videoSwitch[0]?.description}
</p>
<button
class="link"
on:click="{() => {
navigate(col.videoSwitch[0]?.link)
}}">MEHR</button
>
</div>
<video
class="video"
playsinline
src="{`${apiBaseURL}content/${siteId}/${col.videoSwitch[0].video?.src}`}"
loop
alt="video1"
muted
bind:this="{videoElements[0]}"><track kind="captions" /></video
>
</div>
<div class="video-wrapper video-wrapper-small" bind:this="{videoWrappers[1]}">
<div class="text hidden" bind:this="{videoTexts[1]}">
<h2>{col.videoSwitch[1]?.title}</h2>
<p>
{col.videoSwitch[1]?.description}
</p>
<button
class="link"
on:click="{() => {
navigate(col.videoSwitch[1]?.link)
}}">MEHR</button
>
</div>
<video
class="video"
loop
playsinline
src="{`${apiBaseURL}content/${siteId}/${col.videoSwitch[1].video?.src}`}"
muted
bind:this="{videoElements[1]}"><track kind="captions" /></video
>
</div>
</div>
<div class="icons">
<button class="thermo">
<img src="/media/thermometer.svg" alt="temp" />
{Number($temperature).toFixed(1) || "-"} °C
</button>
</div>
</div>
<style lang="less">
@import "../assets/css/variables.less";
.video-top-lvl-container {
width: 100%;
display: flex;
flex-direction: column;
gap: 40px;
}
.video-container {
display: flex;
width: 100%;
@media @mobile {
gap: 20px;
}
@media @tablet {
gap: 40px;
}
}
.icons {
display: flex;
width: 100%;
@media @mobile {
justify-content: end;
}
@media @tablet {
justify-content: end;
button {
margin: 28px 2rem !important;
}
}
margin-bottom: 60px;
img {
transform: scale(1.5);
margin: 0px 0.4rem;
}
button {
display: flex;
font-weight: bold;
justify-content: center;
font-size: 1rem;
position: relative;
margin: 0 1rem;
}
button::before {
font-weight: 400;
position: absolute;
transform: translateY(-150%);
}
.camera::before {
content: "Webcam";
}
.thermo::before {
content: "Lufttemperatur";
}
.waves::before {
content: "Wassertemperatur";
}
}
.video-wrapper {
overflow: hidden;
position: relative;
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.3);
z-index: 10;
}
@media @mobile {
.hidden {
p,
button {
visibility: hidden !important;
opacity: 0;
height: 0px;
margin-top: 0px !important;
transition: opacity 0s;
}
h2 {
margin-bottom: 0px !important;
transform: translateY(50%);
}
}
.shown {
opacity: 1;
visibility: visible;
}
}
@media @desktop {
.hidden {
h2 {
visibility: hidden;
transition: opacity 0s;
}
}
}
.text {
position: absolute;
z-index: 20;
max-width: 85%;
color: rgb(255, 255, 255);
animation-delay: 500ms;
bottom: 35px;
left: 35px;
@media @mobile {
h2 {
font-size: 2.8rem;
font-weight: bold;
line-height: normal;
margin-bottom: 5px;
}
p {
line-height: normal;
}
button {
border-top: 3px solid white;
font-weight: bold;
padding-top: 2px;
color: white;
font-size: 16px;
margin-top: 15px;
}
}
@media @desktop {
max-width: 70%;
h2 {
font-size: 2.7rem;
}
p {
}
button {
font-size: 24px;
}
}
}
}
.video {
width: 100%;
min-height: max(35vh, 400px);
height: auto;
object-fit: cover;
position: absolute;
top: 0;
left: 0;
}
.video-wrapper-big {
flex: 3;
}
.video-wrapper-small {
flex: 1 !important;
}
.video-wrapper-big:hover,
.video-wrapper-small:hover {
flex: 3;
}
@media (max-width: 1023px) {
.video-container {
flex-direction: column;
}
.text {
max-width: 90%;
}
video {
height: 100% !important;
min-height: 75vh !important;
width: auto !important;
min-width: 100%;
object-fit: cover;
object-position: center;
}
.video-wrapper-small,
.video-wrapper-big {
width: 100%;
}
}
</style>

View File

@@ -1,6 +1,6 @@
import { api } from "../../api"
export async function loadBanner(): Promise<Banner[]> {
let banner = await api<any>("banner", {})
return banner.data.map(e => e.banner)
let banner = await api<Site>("banner", {})
return banner.data.map(e=> e.banner)
}

View File

@@ -1,7 +1,7 @@
export default function inView(node, params = { threshold: 0 }) {
let observer
export default function inView(node: Element, params = { threshold: 0 }) {
let observer: IntersectionObserver
const handleIntersect = (e) => {
const handleIntersect = (e: any) => {
const v = e[0].isIntersecting ? "enter" : "exit"
node.dispatchEvent(new CustomEvent(v))
}
@@ -16,7 +16,7 @@ export default function inView(node, params = { threshold: 0 }) {
setObserver(params)
return {
update(params) {
update(params: any) {
setObserver(params)
},

View File

@@ -1,6 +1,6 @@
import { api } from "../../api"
export async function sendForm(body) {
export async function sendForm(body: any) {
let response: any
response = await api("forms", { method: "POST" }, { formular: body })
return response

View File

@@ -1,6 +1,6 @@
export function validateFields(fieldsArray): string[] {
export function validateFields(fieldsArray: (string | boolean | any[])[][]): (string | (() => void))[][] {
const errors = []
let selectedGroup
let selectedGroup: number
const numberRegex = /^[+]?([.]\d+|\d+([.]\d+)?)$/
const emailRegex =
/(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/
@@ -15,13 +15,14 @@ export function validateFields(fieldsArray): string[] {
blockContainer[0].classList.add("invalidBlocks")
}
const validateNumber = (value, field, element) => {
const validateNumber = (value: string, field: any, element: HTMLElement) => {
if (!numberRegex.test(`${value}`)) errors.push(["block", () => element.classList.add("border-red")])
}
fieldsArray.forEach(([field, value]) => {
if (field === "blockGroups" || field.includes("numberLabel")) {
if (field === "blockGroups" || (typeof field === "string" && field.includes("numberLabel"))) {
if (!field.includes("numberLabel")) return
// @ts-ignore
const [elementValue, element, group, boolean] = value
if (!elementValue) return
if (selectedGroup !== undefined) {
@@ -33,29 +34,31 @@ export function validateFields(fieldsArray): string[] {
}
return
}
value = value as any[]
let required = value[1]
value = value[0]
if (!required && !value) return
if (!value) {
errors.push(["Eingabe ist erforderlich.", field])
} else if (field.includes("number_")) {
if (!numberRegex.test(`${value}`)) errors.push(["Ungültiger numerischer Wert.", field])
} else if (field.includes("agreement_")) {
if (value !== true) errors.push(["Bitte das Kontrollkästchen anklicken.", field])
} else if (field.includes("Email_")) {
if (!emailRegex.test(value)) errors.push(["Ungültiges E-Mail-Format.", field])
} else if (field.includes("date_")) {
if (!dateRegex.test(value)) errors.push(["Ungültiges Datumsformat.", field])
} else if (field.includes("times_")) {
if (!timeRegex.test(value)) errors.push(["Ungültiges Zeitformat.", field])
} else if (field.includes("Telefon_")) {
if (!phoneRegex.test(value)) errors.push(["Ungültiges Telefonnummernformat.", field])
} else if (typeof field === "string") {
if (field.includes("number_")) {
if (!numberRegex.test(`${value}`)) errors.push(["Ungültiger numerischer Wert.", field])
} else if (field.includes("agreement_")) {
if (value !== true) errors.push(["Bitte das Kontrollkästchen anklicken.", field])
} else if (field.includes("Email_")) {
if (!emailRegex.test(value as string)) errors.push(["Ungültiges E-Mail-Format.", field])
} else if (field.includes("date_")) {
if (!dateRegex.test(value as string)) errors.push(["Ungültiges Datumsformat.", field])
} else if (field.includes("times_")) {
if (!timeRegex.test(value as string)) errors.push(["Ungültiges Zeitformat.", field])
} else if (field.includes("Telefon_")) {
if (!phoneRegex.test(value as string)) errors.push(["Ungültiges Telefonnummernformat.", field])
}
}
})
const blockContainer = document.getElementsByClassName("blockContainer")
// @ts-ignore
if (blockContainer.length && selectedGroup === undefined) {
console.log("NO SELECTED GROUP")
errors.push(["block", wholeBlockInvalid])
}