Update to latest solidjs and added some spice

This commit is contained in:
aronmal 2024-02-23 19:08:09 +01:00
parent fad746ceec
commit b09418b3ec
Signed by: aronmal
GPG key ID: 816B7707426FC612
35 changed files with 4318 additions and 2831 deletions

3
.gitignore vendored
View file

@ -1,6 +1,5 @@
dist
.solid
.vinxi
.output
.vercel
.netlify

View file

@ -1,36 +1,34 @@
{
"name": "jg-eucs",
"scripts": {
"dev": "solid-start dev",
"build": "solid-start build",
"start": "solid-start start",
"dev": "vinxi dev",
"build": "vinxi build",
"start": "vinxi start",
"lint": "eslint --fix \"src/**/*.{ts,tsx,js,jsx}\"",
"typecheck": "tsc --noEmit --checkJs false --skipLibCheck"
},
"type": "module",
"devDependencies": {
"@types/node": "^20.8.10",
"@typescript-eslint/parser": "^6.9.1",
"esbuild": "^0.19.5",
"eslint": "^8.52.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-solid": "^0.13.0",
"postcss": "^8.4.31",
"prettier": "^3.0.3",
"prettier-plugin-organize-imports": "^3.2.3",
"solid-start-node": "^0.3.9",
"typescript": "^5.2.2",
"vite": "^4.5.0"
"@types/node": "^20.11.20",
"@typescript-eslint/parser": "^7.0.2",
"esbuild": "^0.20.1",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-solid": "^0.13.1",
"prettier": "^3.2.5",
"prettier-plugin-organize-imports": "^3.2.4",
"typescript": "^5.3.3"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^6.4.2",
"@fortawesome/free-brands-svg-icons": "^6.4.2",
"@fortawesome/pro-regular-svg-icons": "^6.4.2",
"@solidjs/meta": "^0.29.1",
"@solidjs/router": "^0.8.3",
"sass": "^1.69.5",
"solid-js": "^1.8.5",
"solid-start": "^0.3.9"
"@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-brands-svg-icons": "^6.5.1",
"@fortawesome/pro-regular-svg-icons": "^6.5.1",
"@solidjs/meta": "^0.29.3",
"@solidjs/router": "^0.12.4",
"@solidjs/start": "^0.5.10",
"sass": "^1.71.1",
"solid-js": "^1.8.15",
"vinxi": "^0.3.3"
},
"engines": {
"node": ">=18"

5834
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

40
public/sitemap.xml Normal file
View file

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/sitemap.xsl"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://jg-eucs.com/en</loc>
<lastmod>2023-11-03</lastmod>
</url>
<url>
<loc>https://jg-eucs.com/en/KSS22</loc>
<lastmod>2023-11-03</lastmod>
</url>
<url>
<loc>https://jg-eucs.com/en/manufacturers</loc>
<lastmod>2023-11-03</lastmod>
</url>
<url>
<loc>https://jg-eucs.com/en/overview</loc>
<lastmod>2023-11-03</lastmod>
</url>
<url>
<loc>https://jg-eucs.com/de</loc>
<lastmod>2023-11-03</lastmod>
</url>
<url>
<loc>https://jg-eucs.com/de/imprint</loc>
<lastmod>2023-11-03</lastmod>
</url>
<url>
<loc>https://jg-eucs.com/de/KSS22</loc>
<lastmod>2023-11-03</lastmod>
</url>
<url>
<loc>https://jg-eucs.com/de/manufacturers</loc>
<lastmod>2023-11-03</lastmod>
</url>
<url>
<loc>https://jg-eucs.com/de/overview</loc>
<lastmod>2023-11-03</lastmod>
</url>
</urlset>

108
public/sitemap.xsl Normal file
View file

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>XML Sitemap</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
body {
font-family: sans-serif;
font-size: 16px;
color: #242628;
}
a {
color: #000;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
table {
border: none;
border-collapse: collapse;
width: 100%
}
th {
text-align: left;
padding-right: 30px;
font-size: 11px;
}
thead th {
border-bottom: 1px solid #7d878a;
cursor: pointer;
}
td {
font-size:11px;
padding: 5px;
}
tr:nth-child(odd) td {
background-color: rgba(0,0,0,0.04);
}
tr:hover td {
background-color: #e2edf2;
}
#content {
margin: 0 auto;
padding: 2% 5%;
max-width: 800px;
}
.desc {
margin: 18px 3px;
line-height: 1.2em;
}
.desc a {
color: #5ba4e5;
}
</style>
</head>
<body>
<div id="content">
<h1>XML Sitemap</h1>
<p class="desc">
This is a sitemap created by <a href="https://unlimited-dev.de">Unlimited Development</a> to allow search engines to discover this site's content.
</p>
<table id="sitemap" cellpadding="3">
<thead>
<tr>
<th width="70%">URL (<xsl:value-of select="count(sitemap:urlset/sitemap:url)"/> total)</th>
<th width="15%">Images</th>
<th title="Last Modification Time" width="15%">Last Modified</th>
</tr>
</thead>
<tbody>
<xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:for-each select="sitemap:urlset/sitemap:url">
<tr>
<td>
<xsl:variable name="itemURL">
<xsl:value-of select="sitemap:loc"/>
</xsl:variable>
<a href="{$itemURL}">
<xsl:value-of select="sitemap:loc"/>
</a>
</td>
<td>
<xsl:value-of select="count(image:image)"/>
</td>
<td>
<xsl:value-of select="concat(substring(sitemap:lastmod,0,11),concat(' ', substring(sitemap:lastmod,12,5)))"/>
</td>
</tr>
</xsl:for-each>
</tbody>
</table>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

110
src/app.tsx Normal file
View file

@ -0,0 +1,110 @@
// @refresh reload
import "@fortawesome/fontawesome-svg-core/styles.css";
import { Link, Meta, MetaProvider, Title } from "@solidjs/meta";
import { Router } from "@solidjs/router";
import { FileRoutes } from "@solidjs/start";
import { Suspense } from "solid-js";
import "./styles/global.scss";
export default function App() {
return (
<Router
root={(props) => (
<MetaProvider>
<Link
rel="apple-touch-icon"
sizes="57x57"
href="/favicon/apple-icon-57x57.png"
/>
<Link
rel="apple-touch-icon"
sizes="60x60"
href="/favicon/apple-icon-60x60.png"
/>
<Link
rel="apple-touch-icon"
sizes="72x72"
href="/favicon/apple-icon-72x72.png"
/>
<Link
rel="apple-touch-icon"
sizes="76x76"
href="/favicon/apple-icon-76x76.png"
/>
<Link
rel="apple-touch-icon"
sizes="114x114"
href="/favicon/apple-icon-114x114.png"
/>
<Link
rel="apple-touch-icon"
sizes="120x120"
href="/favicon/apple-icon-120x120.png"
/>
<Link
rel="apple-touch-icon"
sizes="144x144"
href="/favicon/apple-icon-144x144.png"
/>
<Link
rel="apple-touch-icon"
sizes="152x152"
href="/favicon/apple-icon-152x152.png"
/>
<Link
rel="apple-touch-icon"
sizes="180x180"
href="/favicon/apple-icon-180x180.png"
/>
<Link
rel="icon"
type="image/png"
sizes="192x192"
href="/favicon/android-icon-192x192.png"
/>
<Link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicon/favicon-32x32.png"
/>
<Link
rel="icon"
type="image/png"
sizes="96x96"
href="/favicon/favicon-96x96.png"
/>
<Link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicon/favicon-16x16.png"
/>
<Link rel="manifest" href="/favicon/manifest.json" />
<Meta name="msapplication-TileColor" content="#ffffff" />
<Meta
name="msapplication-TileImage"
content="/favicon/ms-icon-144x144.png"
/>
<Meta name="theme-color" content="#ffffff" />
<Meta http-equiv="X-UA-Compatible" content="IE=edge" />
<Meta charset="UTF-8" />
<Meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
<Meta name="author" content="Julian Gerhardt" />
<Meta
name="keywords"
content="Elektrische Einräder, EUC, Monowheels, Kingsong, Inmotion, Gotway"
/>
<Title>jg-eucs.com</Title>
<Suspense>{props.children}</Suspense>
</MetaProvider>
)}
>
<FileRoutes />
</Router>
);
}

View file

@ -1,9 +1,8 @@
import { Show } from "solid-js";
import { A } from "solid-start";
function DeviceTile(props: { href?: string; name: string; src: string }) {
return (
<A href={props.href ?? "/soon"}>
<a href={props.href ?? "/soon"}>
<h3>{props.name}</h3>
<Show when={props.src.startsWith("/images")}>
<img src={props.src} alt={props.name} />
@ -13,7 +12,7 @@ function DeviceTile(props: { href?: string; name: string; src: string }) {
<source src={props.src} type="video/mp4" />
</video>
</Show>
</A>
</a>
);
}

View file

@ -0,0 +1,82 @@
import { JSX, createEffect, createSignal, onCleanup } from "solid-js";
function ProgressHandler() {
const [scrollPercentage, setScrollPercentage] = createSignal(0);
// const [active, setActive] = createSignal("");
// const [zoomLevel, setZoomLevel] = createSignal(0);
// const zoomAmount = () => 1 + zoomLevel() * 0.5;
// const [x, setX] = createSignal(0);
// const [y, setY] = createSignal(0);
function ProgressBar() {
// const [muted, setMuted] = createSignal(true);
// const [controlls, setControlls] = createSignal(false);
// const [clientX, setClientX] = createSignal(0);
// const [clientY, setClientY] = createSignal(0);
// const [ref, setRef] = createSignal<HTMLElement | null>(null);
const handleScroll = () => {
const scrollHeight =
document.documentElement.scrollHeight - window.innerHeight;
const currentScroll = window.scrollY;
const scrollPercentage = (currentScroll / scrollHeight) * 100;
setScrollPercentage(scrollPercentage);
};
createEffect(() => {
window.addEventListener("scroll", handleScroll);
onCleanup(() => {
window.removeEventListener("scroll", handleScroll);
});
});
createEffect(() => {
// const thisRef = ref();
// if (!thisRef) return;
// const rectA = thisRef.getBoundingClientRect();
// const origSizeW = rectA.width / zoomAmount();
// const origSizeH = rectA.height / zoomAmount();
// const rectW = wrapperRef.getBoundingClientRect();
// const hori = rectW.width - origSizeW + origSizeW / zoomAmount();
// const verti = rectW.height - origSizeH + origSizeH / zoomAmount();
// const xP = (clientX() - hori / 2) / (rectW.width - hori);
// const yP = (clientY() - verti / 2) / (rectW.height - verti);
// setX((xP > 0 ? (xP < 1 ? xP : 1) : 0) * origSizeW);
// setY((yP > 0 ? (yP < 1 ? yP : 1) : 0) * origSizeH);
// const moving =
// clientX() > (rectW.width - origSizeW) / 2 &&
// clientX() < rectW.width - (rectW.width - origSizeW) / 2 &&
// clientY() > (rectW.height - origSizeH) / 2 &&
// clientY() < rectW.height - (rectW.height - origSizeH) / 2;
// setMoving(moving);
});
// let wrapperRef: HTMLDivElement;
createEffect(() => {
// if (active()) return;
// setZoomLevel(0);
// setMuted(true);
// setControlls(false);
});
return (
<div class="progress">
<></>
</div>
);
}
function Chapter(props: { children: JSX.Element }) {
let divRef: HTMLDivElement;
// let videoRef: HTMLVideoElement;
// const shouldZoom = () => active() === props.src && !!zoomLevel();
return <div ref={divRef!}>{props.children}</div>;
}
return { FullscreenView: ProgressBar, Asset: Chapter };
}
export default ProgressHandler;

View file

@ -4,7 +4,6 @@ import {
faHashtag,
} from "@fortawesome/pro-regular-svg-icons";
import { JSXElement, Show, createMemo } from "solid-js";
import { A } from "solid-start";
import { FontAwesomeIcon } from "./FontAwesomeIcon";
const types = {
@ -38,7 +37,7 @@ function R(props: {
return (
<>
{" "}
<A
<a
href={props.href}
target={type() === "external" ? "_blank" : ""}
rel={type() === "external" ? "noreferrer noopener" : ""}
@ -52,7 +51,7 @@ function R(props: {
<Show when={type() !== "id"}>
<FontAwesomeIcon class="right" icon={types[type()]} title={type()} />
</Show>
</A>{" "}
</a>{" "}
</>
);
}

View file

@ -0,0 +1,15 @@
import { JSX, Suspense } from "solid-js";
function Wrapper(props: {
class: string;
classList: Record<string, boolean>;
children: JSX.Element | JSX.Element[];
}) {
return (
<div id="body" class={props.class} classList={props.classList}>
<Suspense>{props.children}</Suspense>
</div>
);
}
export default Wrapper;

View file

@ -6,18 +6,38 @@ import {
faGlobe,
faXmark,
} from "@fortawesome/pro-regular-svg-icons";
import {
useIsRouting,
useLocation,
useNavigate,
useSearchParams,
} from "@solidjs/router";
import { createEffect, createSignal, onCleanup } from "solid-js";
import { A, useIsRouting, useLocation, useNavigate } from "solid-start";
import { FontAwesomeIcon } from "../FontAwesomeIcon";
export const [lightMode, setLightMode] = createSignal(false);
const [menu, setMenu] = createSignal(false);
function Navbar() {
const [menu, setMenu] = createSignal(false);
const navigate = useNavigate();
const location = useLocation();
const [searchParams] = useSearchParams();
const isRouting = useIsRouting();
createEffect(() => {
const mode = searchParams.lightMode;
const prefersDarkMode =
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches;
if (typeof mode === "undefined") {
setLightMode(!prefersDarkMode);
return;
}
const parsedMode = JSON.parse(mode);
if (typeof parsedMode !== "boolean") return;
setLightMode(parsedMode);
});
createEffect(() => {
if (!isRouting() || !menu()) return;
setMenu(false);
@ -39,83 +59,94 @@ function Navbar() {
return (
<>
<div id="navbar" style={{ visibility: menu() ? "visible" : "hidden" }}>
<A href="/de/">
<a href="/de/">
<FontAwesomeIcon icon={faBookOpen} /> Einführung
</A>
</a>
<A href="/de/overview">
<a href="/de/overview">
<FontAwesomeIcon icon={faBookOpen} /> Start
</A>
</a>
<ol>
<li>
<A href="/de/overview#start">Was sind EUCs?</A>
<a href="/de/overview#start">Was sind EUCs?</a>
</li>
<li>
<A href="/de/overview#why">Warum EUCs?</A>
<a href="/de/overview#why">Warum EUCs?</a>
</li>
<li>
<A href="/de/overview#funktion">Funktionsweise</A>
<a href="/de/overview#funktion">Funktionsweise</a>
</li>
<li>
<A href="/de/overview#begriffe">Begriffe</A>
<a href="/de/overview#begriffe">Begriffe</a>
</li>
<li>
<A href="/de/overview#sicherheit">Sicherheit</A>
<a href="/de/overview#sicherheit">Sicherheit</a>
</li>
<li>
<A href="/de/overview#ausrüstung">Ausrüstung</A>
<a href="/de/overview#ausrüstung">Ausrüstung</a>
</li>
<li>
<A href="/de/overview#cutout">Cut-out's</A>
<a href="/de/overview#cutout">Cut-out's</a>
</li>
<li>
<A href="/de/overview#akkuss">Akkusicherheit</A>
<a href="/de/overview#akkuss">Akkusicherheit</a>
</li>
<li>
<A href="/de/overview#fahrweise">Fahrweise</A>
<a href="/de/overview#fahrweise">Fahrweise</a>
</li>
<li>
<A href="/de/overview#wobbles">Wobbles</A>
<a href="/de/overview#wobbles">Wobbles</a>
</li>
<li>
<A href="/de/overview#leistung">Leistung</A>
<a href="/de/overview#leistung">Leistung</a>
</li>
<li>
<A href="/de/overview#federung">Federung</A>
<a href="/de/overview#federung">Federung</a>
</li>
<li>
<A href="/de/overview#reifen">Reifen</A>
<a href="/de/overview#reifen">Reifen</a>
</li>
<li>
<A href="/de/overview#historie">Historie</A>
<a href="/de/overview#historie">Historie</a>
</li>
<li>
<A href="/de/overview#geraete">Geräte Liste</A>
<a href="/de/overview#geraete">Geräte Liste</a>
</li>
</ol>
<A href="/de/manufacturers">
<a href="/de/manufacturers">
<FontAwesomeIcon icon={faBookOpen} /> Hersteller
</A>
</a>
<A href="/de/imprint">
<a href="/de/imprint">
<FontAwesomeIcon icon={faGavel} /> Impressum
</A>
</a>
<button onClick={() => setLightMode((e) => !e)}>
{lightMode() ? "Dark Mode " : "Light Mode "}
<FontAwesomeIcon icon={faCircleHalfStroke} />
</button>
<button
onClick={() =>
navigate("/en" + location.pathname.slice(3), { scroll: false })
}
>
Englisch <FontAwesomeIcon icon={faGlobe} />
</button>
<button onClick={() => setMenu(false)}>
Close <FontAwesomeIcon icon={faXmark} />
</button>
<div class="modes">
<button
onClick={() => {
const mode = !lightMode() ? "?lightMode=true" : "";
const url = location.pathname + mode;
navigate(url, {
replace: true,
scroll: false,
});
}}
>
{lightMode() ? "Dark Mode " : "Light Mode "}
<FontAwesomeIcon icon={faCircleHalfStroke} />
</button>
<button
onClick={() =>
navigate("/en" + location.pathname.slice(3), { scroll: false })
}
>
Englisch <FontAwesomeIcon icon={faGlobe} />
</button>
<button onClick={() => setMenu(false)}>
Close <FontAwesomeIcon icon={faXmark} />
</button>
</div>
</div>
<button class="menu" title="Menu" onClick={() => setMenu(true)}>

View file

@ -6,18 +6,38 @@ import {
faGlobe,
faXmark,
} from "@fortawesome/pro-regular-svg-icons";
import {
useIsRouting,
useLocation,
useNavigate,
useSearchParams,
} from "@solidjs/router";
import { createEffect, createSignal, onCleanup } from "solid-js";
import { A, useIsRouting, useLocation, useNavigate } from "solid-start";
import { FontAwesomeIcon } from "../FontAwesomeIcon";
export const [lightMode, setLightMode] = createSignal(false);
const [menu, setMenu] = createSignal(false);
function Navbar() {
const [menu, setMenu] = createSignal(false);
const navigate = useNavigate();
const location = useLocation();
const [searchParams] = useSearchParams();
const isRouting = useIsRouting();
createEffect(() => {
const mode = searchParams.lightMode;
const prefersDarkMode =
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches;
if (typeof mode === "undefined") {
setLightMode(!prefersDarkMode);
return;
}
const parsedMode = JSON.parse(mode);
if (typeof parsedMode !== "boolean") return;
setLightMode(parsedMode);
});
createEffect(() => {
if (!isRouting() || !menu()) return;
setMenu(false);
@ -39,83 +59,94 @@ function Navbar() {
return (
<>
<div id="navbar" style={{ visibility: menu() ? "visible" : "hidden" }}>
<A href="/en/">
<a href="/en/">
<FontAwesomeIcon icon={faBookOpen} /> Introduction
</A>
</a>
<A href="/en/overview">
<a href="/en/overview">
<FontAwesomeIcon icon={faBookOpen} /> Start
</A>
</a>
<ol>
<li>
<A href="/en/overview#start">What are EUCs?</A>
<a href="/en/overview#start">What are EUCs?</a>
</li>
<li>
<A href="/en/overview#why">Why EUCs?</A>
<a href="/en/overview#why">Why EUCs?</a>
</li>
<li>
<A href="/en/overview#funktion">Functionality</A>
<a href="/en/overview#funktion">Functionality</a>
</li>
<li>
<A href="/en/overview#begriffe">Glossarry</A>
<a href="/en/overview#begriffe">Glossarry</a>
</li>
<li>
<A href="/en/overview#sicherheit">Safety</A>
<a href="/en/overview#sicherheit">Safety</a>
</li>
<li>
<A href="/en/overview#ausrüstung">Gear</A>
<a href="/en/overview#ausrüstung">Gear</a>
</li>
<li>
<A href="/en/overview#cutout">Cut-out's</A>
<a href="/en/overview#cutout">Cut-out's</a>
</li>
<li>
<A href="/en/overview#akkuss">Battery safety</A>
<a href="/en/overview#akkuss">Battery safety</a>
</li>
<li>
<A href="/en/overview#fahrweise">Ride style</A>
<a href="/en/overview#fahrweise">Ride style</a>
</li>
<li>
<A href="/en/overview#wobbles">Wobbles</A>
<a href="/en/overview#wobbles">Wobbles</a>
</li>
<li>
<A href="/en/overview#leistung">Performance</A>
<a href="/en/overview#leistung">Performance</a>
</li>
<li>
<A href="/en/overview#federung">Suspension</A>
<a href="/en/overview#federung">Suspension</a>
</li>
<li>
<A href="/en/overview#reifen">Tires</A>
<a href="/en/overview#reifen">Tires</a>
</li>
<li>
<A href="/en/overview#historie">History</A>
<a href="/en/overview#historie">History</a>
</li>
<li>
<A href="/en/overview#geraete">Device list</A>
<a href="/en/overview#geraete">Device list</a>
</li>
</ol>
<A href="/en/manufacturers">
<a href="/en/manufacturers">
<FontAwesomeIcon icon={faBookOpen} /> Manufacturers
</A>
</a>
<A href="/de/imprint">
<a href="/de/imprint">
<FontAwesomeIcon icon={faGavel} /> Legal Notice (DE)
</A>
</a>
<button onClick={() => setLightMode((e) => !e)}>
{lightMode() ? "Dark Mode " : "Light Mode "}
<FontAwesomeIcon icon={faCircleHalfStroke} />
</button>
<button
onClick={() =>
navigate("/de" + location.pathname.slice(3), { scroll: false })
}
>
Deutsch <FontAwesomeIcon icon={faGlobe} />
</button>
<button onClick={() => setMenu(false)}>
Close <FontAwesomeIcon icon={faXmark} />
</button>
<div class="modes">
<button
onClick={() => {
const mode = !lightMode() ? "?lightMode=true" : "";
const url = location.pathname + mode;
navigate(url, {
replace: true,
scroll: false,
});
}}
>
{lightMode() ? "Dark Mode " : "Light Mode "}
<FontAwesomeIcon icon={faCircleHalfStroke} />
</button>
<button
onClick={() =>
navigate("/de" + location.pathname.slice(3), { scroll: false })
}
>
Deutsch <FontAwesomeIcon icon={faGlobe} />
</button>
<button onClick={() => setMenu(false)}>
Close <FontAwesomeIcon icon={faXmark} />
</button>
</div>
</div>
<button class="menu" title="Menu" onClick={() => setMenu(true)}>

View file

@ -1,3 +1,3 @@
import { mount, StartClient } from "solid-start/entry-client";
import { mount, StartClient } from "@solidjs/start/client";
mount(() => <StartClient />, document);
mount(() => <StartClient />, document.getElementById("app")!);

View file

@ -1,9 +1,19 @@
import {
createHandler,
renderAsync,
StartServer,
} from "solid-start/entry-server";
import { StartServer, createHandler } from "@solidjs/start/server";
export default createHandler(
renderAsync((event) => <StartServer event={event} />),
);
export default createHandler(() => (
<StartServer
document={({ assets, children, scripts }) => (
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
{assets}
</head>
<body id="app">
{children}
{scripts}
</body>
</html>
)}
/>
));

2
src/global.d.ts vendored
View file

@ -1 +1 @@
/// <reference types="solid-start/env" />
/// <reference types="@solidjs/start/env" />

View file

@ -1,116 +0,0 @@
// @refresh reload
import "@fortawesome/fontawesome-svg-core/styles.css";
import { Suspense } from "solid-js";
import {
FileRoutes,
Head,
Html,
Link,
Meta,
Routes,
Scripts,
Title,
useLocation,
} from "solid-start";
import "~/styles/global.scss";
export default function Root() {
const location = useLocation();
return (
<Html lang={location.pathname.startsWith("/de") ? "de" : "en"}>
<Head>
<Link
rel="apple-touch-icon"
sizes="57x57"
href="/favicon/apple-icon-57x57.png"
/>
<Link
rel="apple-touch-icon"
sizes="60x60"
href="/favicon/apple-icon-60x60.png"
/>
<Link
rel="apple-touch-icon"
sizes="72x72"
href="/favicon/apple-icon-72x72.png"
/>
<Link
rel="apple-touch-icon"
sizes="76x76"
href="/favicon/apple-icon-76x76.png"
/>
<Link
rel="apple-touch-icon"
sizes="114x114"
href="/favicon/apple-icon-114x114.png"
/>
<Link
rel="apple-touch-icon"
sizes="120x120"
href="/favicon/apple-icon-120x120.png"
/>
<Link
rel="apple-touch-icon"
sizes="144x144"
href="/favicon/apple-icon-144x144.png"
/>
<Link
rel="apple-touch-icon"
sizes="152x152"
href="/favicon/apple-icon-152x152.png"
/>
<Link
rel="apple-touch-icon"
sizes="180x180"
href="/favicon/apple-icon-180x180.png"
/>
<Link
rel="icon"
type="image/png"
sizes="192x192"
href="/favicon/android-icon-192x192.png"
/>
<Link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicon/favicon-32x32.png"
/>
<Link
rel="icon"
type="image/png"
sizes="96x96"
href="/favicon/favicon-96x96.png"
/>
<Link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicon/favicon-16x16.png"
/>
<Link rel="manifest" href="/favicon/manifest.json" />
<Meta name="msapplication-TileColor" content="#ffffff" />
<Meta
name="msapplication-TileImage"
content="/favicon/ms-icon-144x144.png"
/>
<Meta name="theme-color" content="#ffffff" />
<Meta http-equiv="X-UA-Compatible" content="IE=edge" />
<Meta charset="UTF-8" />
<Meta name="viewport" content="width=device-width, initial-scale=1.0" />
<Meta name="author" content="Julian Gerhardt" />
<Meta
name="keywords"
content="Elektrische Einräder, EUC, Monowheels, Kingsong, Inmotion, Gotway"
/>
<Title>SolidStart - Bare</Title>
</Head>
<Suspense>
<Routes>
<FileRoutes />
</Routes>
</Suspense>
<Scripts />
</Html>
);
}

View file

@ -1,19 +1,26 @@
import { Title } from "solid-start";
import { HttpStatusCode } from "solid-start/server";
import { Title } from "@solidjs/meta";
import { useNavigate } from "@solidjs/router";
import { HttpStatusCode } from "@solidjs/start";
import Wrapper from "~/components/Wrapper";
import Navbar from "~/components/en/Navbar";
import "~/styles/overview.scss";
export default function NotFound() {
const navigate = useNavigate();
return (
<main>
<Wrapper class="overview">
<Title>Not Found</Title>
<HttpStatusCode code={404} />
<h1>Page Not Found</h1>
<p>
Visit{" "}
<a href="https://start.solidjs.com" target="_blank">
start.solidjs.com
</a>{" "}
to learn how to build SolidStart apps.
</p>
</main>
<Navbar />
<div
style={{
"min-height": "100vh",
display: "inline-block",
}}
>
<p style={{ "text-align": "center" }}>This side could not be found.</p>
<button onClick={() => navigate(-1)}>Back</button>
</div>
</Wrapper>
);
}

View file

@ -1,12 +1,13 @@
import { Body, Title } from "solid-start";
import { Title } from "@solidjs/meta";
import AssetHandler from "~/components/Asset";
import Wrapper from "~/components/Wrapper";
import Navbar, { lightMode } from "~/components/en/Navbar";
import "~/styles/devices.scss";
function KSS22() {
const { FullscreenView, Asset } = AssetHandler();
return (
<Body class="devices" classList={{ "light-mode": lightMode() }}>
<Wrapper class="devices" classList={{ "light-mode": lightMode() }}>
<Title>KS S22</Title>
<FullscreenView />
<Navbar />
@ -215,7 +216,7 @@ function KSS22() {
</tbody>
</table>
</article>
</Body>
</Wrapper>
);
}

View file

@ -1,14 +1,20 @@
import { Body, Title } from "solid-start";
import { Title } from "@solidjs/meta";
import Wrapper from "~/components/Wrapper";
import Navbar, { lightMode } from "~/components/en/Navbar";
import "~/styles/overview.scss";
function imprint() {
return (
<Body class="overview" classList={{ "light-mode": lightMode() }}>
<Wrapper class="overview" classList={{ "light-mode": lightMode() }}>
<Title>Impressum</Title>
<Navbar />
<article>
<article
style={{
"min-height": "100vh",
display: "inline-block",
}}
>
<h1>Impressum</h1>
<h2>Verantwortlich für den Inhalt gemäß § 18 Abs. 1 MStV:</h2>
@ -42,7 +48,7 @@ function imprint() {
Inhalt verantwortlich ist.
</p>
</article>
</Body>
</Wrapper>
);
}

View file

@ -1,15 +1,16 @@
import { faYoutube } from "@fortawesome/free-brands-svg-icons";
import { faBookOpen, faGlobe } from "@fortawesome/pro-regular-svg-icons";
import { A, Body, Title } from "solid-start";
import { Title } from "@solidjs/meta";
import AssetHandler from "~/components/Asset";
import { FontAwesomeIcon } from "~/components/FontAwesomeIcon";
import Wrapper from "~/components/Wrapper";
import { lightMode } from "~/components/de/Navbar";
import "~/styles/start.scss";
function Introduction() {
const { FullscreenView, Asset } = AssetHandler();
return (
<Body class="start" classList={{ "light-mode": lightMode() }}>
<Wrapper class="start" classList={{ "light-mode": lightMode() }}>
<Title>Einführung</Title>
<FullscreenView />
@ -49,30 +50,30 @@ function Introduction() {
<p>Interessiert? Dann tauche in die Welt der PEV's und EUC's ein:</p>
<A href="/de/overview">
<a href="/de/overview">
<div id="MoreButton">
<p>
Ich will alles darüber lesen! <FontAwesomeIcon icon={faBookOpen} />
</p>
</div>
</A>
</a>
<A href="https:/youtube.com/playlist?list=PLfoxTRt1qLuAg-Al9JNHrl_7KVl-uSxwV">
<a href="https:/youtube.com/playlist?list=PLfoxTRt1qLuAg-Al9JNHrl_7KVl-uSxwV">
<div id="MoreButton">
<p>
Mir reichen Videos <FontAwesomeIcon icon={faYoutube} />
</p>
</div>
</A>
</a>
<A href="/en/">
<a href="/en/">
<div id="MoreButton">
<p>
Switch to English <FontAwesomeIcon icon={faGlobe} />
</p>
</div>
</A>
</Body>
</a>
</Wrapper>
);
}

View file

@ -1,13 +1,14 @@
import { Body, Title } from "solid-start";
import { Title } from "@solidjs/meta";
import AssetHandler from "~/components/Asset";
import R from "~/components/Reference";
import Wrapper from "~/components/Wrapper";
import Navbar, { lightMode } from "~/components/de/Navbar";
import "~/styles/overview.scss";
function Manufacturers() {
const { FullscreenView, Asset } = AssetHandler();
return (
<Body class="overview" classList={{ "light-mode": lightMode() }}>
<Wrapper class="overview" classList={{ "light-mode": lightMode() }}>
<Title>Hersteller</Title>
<FullscreenView />
<Navbar />
@ -204,7 +205,7 @@ function Manufacturers() {
</p>
</div>
</article>
</Body>
</Wrapper>
);
}

View file

@ -1,14 +1,15 @@
import { Body, Title } from "solid-start";
import { Title } from "@solidjs/meta";
import AssetHandler from "~/components/Asset";
import DeviceTile from "~/components/DeviceTile";
import R from "~/components/Reference";
import Wrapper from "~/components/Wrapper";
import Navbar, { lightMode } from "~/components/de/Navbar";
import "~/styles/overview.scss";
function overview() {
const { FullscreenView, Asset } = AssetHandler();
return (
<Body class="overview" classList={{ "light-mode": lightMode() }}>
<Wrapper class="overview" classList={{ "light-mode": lightMode() }}>
<Title>Einführung EUCs</Title>
<FullscreenView />
<Navbar />
@ -1159,7 +1160,7 @@ function overview() {
</div>
</article>
<footer />
</Body>
</Wrapper>
);
}

View file

@ -1,12 +1,13 @@
import { Body, Title } from "solid-start";
import { Title } from "@solidjs/meta";
import AssetHandler from "~/components/Asset";
import Wrapper from "~/components/Wrapper";
import Navbar, { lightMode } from "~/components/en/Navbar";
import "~/styles/devices.scss";
function KSS22() {
const { FullscreenView, Asset } = AssetHandler();
return (
<Body class="devices" classList={{ "light-mode": lightMode() }}>
<Wrapper class="devices" classList={{ "light-mode": lightMode() }}>
<Title>KS S22</Title>
<FullscreenView />
<Navbar />
@ -213,7 +214,7 @@ function KSS22() {
</tbody>
</table>
</article>
</Body>
</Wrapper>
);
}

View file

@ -1,15 +1,16 @@
import { faYoutube } from "@fortawesome/free-brands-svg-icons";
import { faBookOpen, faGlobe } from "@fortawesome/pro-regular-svg-icons";
import { A, Body, Title } from "solid-start";
import { Title } from "@solidjs/meta";
import AssetHandler from "~/components/Asset";
import { FontAwesomeIcon } from "~/components/FontAwesomeIcon";
import Wrapper from "~/components/Wrapper";
import { lightMode } from "~/components/en/Navbar";
import "~/styles/start.scss";
function Introduction() {
const { FullscreenView, Asset } = AssetHandler();
return (
<Body class="start" classList={{ "light-mode": lightMode() }}>
<Wrapper class="start" classList={{ "light-mode": lightMode() }}>
<Title>Introduction</Title>
<FullscreenView />
@ -50,31 +51,31 @@ function Introduction() {
<p>Interested? Then take a deep dive into PEV's and EUC's:</p>
<A href="/en/overview">
<a href="/en/overview">
<div id="MoreButton">
<p>
I want to read everything about it!{" "}
<FontAwesomeIcon icon={faBookOpen} />
</p>
</div>
</A>
</a>
<A href="https:/youtube.com/playlist?list=PLfoxTRt1qLuAg-Al9JNHrl_7KVl-uSxwV">
<a href="https:/youtube.com/playlist?list=PLfoxTRt1qLuAg-Al9JNHrl_7KVl-uSxwV">
<div id="MoreButton">
<p>
Na, videos are just fine <FontAwesomeIcon icon={faYoutube} />
</p>
</div>
</A>
</a>
<A href="/de/">
<a href="/de/">
<div id="MoreButton">
<p>
Wechsel zu Deutsch <FontAwesomeIcon icon={faGlobe} />
</p>
</div>
</A>
</Body>
</a>
</Wrapper>
);
}

View file

@ -1,13 +1,14 @@
import { Body, Title } from "solid-start";
import { Title } from "@solidjs/meta";
import AssetHandler from "~/components/Asset";
import R from "~/components/Reference";
import Wrapper from "~/components/Wrapper";
import Navbar, { lightMode } from "~/components/en/Navbar";
import "~/styles/overview.scss";
function Manufacturers() {
const { FullscreenView, Asset } = AssetHandler();
return (
<Body class="overview" classList={{ "light-mode": lightMode() }}>
<Wrapper class="overview" classList={{ "light-mode": lightMode() }}>
<Title>Manufacturers</Title>
<FullscreenView />
<Navbar />
@ -195,7 +196,7 @@ function Manufacturers() {
</p>
</div>
</article>
</Body>
</Wrapper>
);
}

View file

@ -1,14 +1,15 @@
import { Body, Title } from "solid-start";
import { Title } from "@solidjs/meta";
import AssetHandler from "~/components/Asset";
import DeviceTile from "~/components/DeviceTile";
import R from "~/components/Reference";
import Wrapper from "~/components/Wrapper";
import Navbar, { lightMode } from "~/components/en/Navbar";
import "~/styles/overview.scss";
function Overview() {
const { FullscreenView, Asset } = AssetHandler();
return (
<Body class="overview" classList={{ "light-mode": lightMode() }}>
<Wrapper class="overview" classList={{ "light-mode": lightMode() }}>
<Title>Introduction EUCs</Title>
<FullscreenView />
<Navbar />
@ -1170,7 +1171,7 @@ function Overview() {
</div>
</article>
<footer />
</Body>
</Wrapper>
);
}

View file

@ -1,5 +1,6 @@
import { Title } from "@solidjs/meta";
import { useNavigate } from "@solidjs/router";
import { createEffect } from "solid-js";
import { Title, useNavigate } from "solid-start";
export default function Home() {
const navigate = useNavigate();

View file

@ -1,16 +1,27 @@
import { Body, Title, useNavigate } from "solid-start";
import { Title } from "@solidjs/meta";
import { useNavigate } from "@solidjs/router";
import Wrapper from "~/components/Wrapper";
import Navbar, { lightMode } from "~/components/en/Navbar";
import "~/styles/overview.scss";
function soon() {
const navigate = useNavigate();
return (
<Body class="overview" classList={{ "light-mode": lightMode() }}>
<Wrapper class="overview" classList={{ "light-mode": lightMode() }}>
<Title>soon</Title>
<Navbar />
<p style={{ "text-align": "center" }}>This side is not available yet.</p>
<button onClick={() => navigate(-1)}>Back</button>
</Body>
<div
style={{
"min-height": "100vh",
display: "inline-block",
}}
>
<p style={{ "text-align": "center" }}>
This side is not available yet.
</p>
<button onClick={() => navigate(-1)}>Back</button>
</div>
</Wrapper>
);
}

View file

@ -16,7 +16,7 @@
background: #555;
}
body.devices {
#body.devices {
background-color: #16161a;
color: #94a1b2;
font-size: 1.4em;

View file

@ -2,210 +2,220 @@ body {
margin: 0;
}
.fullscreen-asset {
position: fixed;
height: 100vh;
width: 100vw;
background-color: rgba(0, 0, 0, 0.8);
z-index: 10;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
&:not(.active) {
display: none;
}
img,
video {
max-width: 80vw;
transform-origin: center;
transform: scale(var(--zoom));
&.active {
opacity: 0;
}
}
img:not(.move),
video:not(.move) {
transition: transform-origin 1s;
}
img.move,
video.move {
transform-origin: var(--x) var(--y);
}
.controlls {
position: absolute;
top: 2rem;
right: 2rem;
#body {
.fullscreen-asset {
position: fixed;
height: 100vh;
width: 100vw;
background-color: rgba(0, 0, 0, 0.8);
z-index: 10;
display: flex;
flex-direction: column;
gap: 1rem;
align-items: center;
justify-content: center;
button {
padding: 0.5rem 0.6rem;
border-radius: 10%;
&:not(.active) {
display: none;
}
svg {
height: 2rem;
width: 2rem;
img,
video {
max-width: 80vw;
transform-origin: center;
transform: scale(var(--zoom));
@media (max-width: 1200px) {
height: 5vw;
width: 5vw;
&.active {
opacity: 0;
}
}
img:not(.move),
video:not(.move) {
transition: transform-origin 1s;
}
img.move,
video.move {
transform-origin: var(--x) var(--y);
}
.controlls {
position: absolute;
top: 2rem;
right: 2rem;
display: flex;
flex-direction: column;
gap: 1rem;
button {
padding: 0.5rem 0.6rem;
border-radius: 10%;
svg {
height: 2rem;
width: 2rem;
@media (max-width: 1200px) {
height: 5vw;
width: 5vw;
}
}
}
}
}
}
.menu {
position: absolute;
top: 2rem;
left: 2rem;
padding: 0.5rem 0.6rem;
border-radius: 10%;
svg {
height: 2rem;
width: 2rem;
}
@media (max-width: 1200px) {
.menu {
position: fixed;
top: 5vw;
left: 5vw;
padding: 2vw;
top: 2rem;
left: 2rem;
padding: 0.5rem 0.6rem;
border-radius: 10%;
svg {
height: 5vw;
width: 5vw;
height: 2rem;
width: 2rem;
}
}
}
article > div {
clear: both;
}
@media (max-width: 1200px) {
position: fixed;
top: 5vw;
left: 5vw;
padding: 2vw;
.righties {
margin-top: -8px;
margin-left: 24px;
width: 33%;
float: right;
clear: both;
}
.lefties {
margin-top: -8px;
margin-right: 24px;
width: 33%;
float: left;
display: none;
}
#navbar {
z-index: 1;
overflow-y: auto;
overflow-x: hidden;
background-color: #121629;
position: fixed;
top: 0;
height: 100%;
margin-left: -8px;
padding: 1rem;
button {
border-radius: 16px;
scale: 0.9;
&:hover {
scale: 1.06;
svg {
height: 5vw;
width: 5vw;
}
}
}
a {
float: none;
display: block;
color: #eff0f3;
text-align: left;
padding: 8px 8px;
text-decoration: none;
font-size: 0.9em;
&:hover {
background: #eff0f3;
color: #121629;
cursor: pointer;
}
article > div {
clear: both;
}
}
body.light-mode {
background-color: #eff0f3;
color: #2a2a2a;
.lefties,
.righties {
> * {
box-shadow: #eff0f3 0 0 1rem 1rem;
margin-top: -8px;
margin-left: 24px;
width: 33%;
float: right;
clear: both;
}
.lefties {
margin-top: -8px;
margin-right: 24px;
width: 33%;
float: left;
display: none;
}
#navbar {
z-index: 1;
overflow-y: auto;
overflow-x: hidden;
background-color: #121629;
position: fixed;
top: 0;
height: 100%;
margin-left: -8px;
padding: 1rem;
.modes {
margin: 1rem 0;
button {
border-radius: 16px;
scale: 0.9;
&:hover {
scale: 1.06;
}
}
}
a {
float: none;
display: block;
color: #eff0f3;
text-align: left;
padding: 8px 8px;
text-decoration: none;
font-size: 0.9em;
&:hover {
background: #eff0f3;
color: #121629;
cursor: pointer;
}
}
}
article p a {
text-align: justify;
text-decoration: underline;
color: #2a2a2a;
}
b {
&.light-mode {
background-color: #eff0f3;
color: #2a2a2a;
.lefties,
.righties {
> * {
box-shadow: #eff0f3 0 0 1rem 1rem;
}
}
article p a {
text-align: justify;
color: #2a2a2a;
border-bottom: 1px solid #2a2a2a;
&:hover {
color: blue;
border-bottom: 1px solid blue;
.svg-inline--fa {
color: blue;
}
}
}
.svg-inline--fa {
color: #2a2a2a;
}
b {
color: #2a2a2a;
a {
color: #2a2a2a;
}
}
h3 {
color: #2a2a2a;
}
h1 {
color: #2a2a2a;
}
h2 {
color: #2a2a2a;
}
#navbar {
background-color: #b8c1ec;
a {
color: black;
}
}
button {
background-color: #b8c1ec;
color: black;
}
.raster > a {
background-color: #eff0f3;
}
a {
color: #2a2a2a;
}
}
h3 {
color: #2a2a2a;
}
h1 {
color: #2a2a2a;
}
h2 {
color: #2a2a2a;
}
#navbar {
background-color: #b8c1ec;
a {
color: black;
}
}
// #sidenavbar {
// background-color: #b8c1ec;
// a {
// color: black;
// }
// }
button {
background-color: #b8c1ec;
color: black;
}
/*Raster Einstellungen*/
.raster > a {
background-color: #eff0f3;
}
a {
color: #2a2a2a;
article {
max-width: 80vw;
margin: auto;
}
}
article {
max-width: 80vw;
margin: auto;
}

View file

@ -21,7 +21,7 @@
background: #555;
}
body.overview {
.overview {
background-color: #16161a;
color: #94a1b2;
text-align: center;
@ -73,6 +73,7 @@ body.overview {
}
p a {
display: inline-block;
text-align: justify;
text-decoration: none;
color: #91c4ff;

View file

@ -21,8 +21,11 @@
background: #555;
}
body.start {
body {
background-color: #0f0e17;
}
#body.start {
color: #a7a9be;
text-align: left;
font-size: 1.4em;

View file

@ -1,14 +1,17 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "node",
"jsxImportSource": "solid-js",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"jsx": "preserve",
"jsxImportSource": "solid-js",
"allowJs": true,
"strict": true,
"baseUrl": "./",
"noEmit": true,
"types": ["vinxi/client"],
"isolatedModules": true,
"paths": {
"~/*": ["./src/*"]
}

View file

@ -1,10 +1,3 @@
import solid from "solid-start/vite";
import { defineConfig } from "vite";
import { defineConfig } from "@solidjs/start/config";
export default defineConfig({
plugins: [solid()],
server: {
host: "0.0.0.0",
strictPort: true,
},
});
export default defineConfig({});