mirror of
https://github.com/TheTaz25/denis.ergin.git
synced 2025-07-06 13:18:49 +00:00
feat(knowledge-base): Rewrite Navigation, add utils, initial page for knowledge-base
This commit is contained in:
parent
20d548bec6
commit
d207c35805
11 changed files with 283 additions and 58 deletions
55
src/components/atoms/Button.astro
Normal file
55
src/components/atoms/Button.astro
Normal file
|
@ -0,0 +1,55 @@
|
|||
---
|
||||
import { clx } from '../../utils/classes';
|
||||
type Props = {
|
||||
className?: string;
|
||||
type?: 'primary' | 'ghost';
|
||||
}
|
||||
|
||||
const { className, type, ...props } = Astro.props;
|
||||
const buttonType = type ?? 'primary'
|
||||
---
|
||||
|
||||
<button class={clx({
|
||||
[buttonType]: true,
|
||||
}, className)} {...props}>
|
||||
<slot />
|
||||
</button>
|
||||
|
||||
<style lang="scss">
|
||||
button {
|
||||
border: none;
|
||||
font-size: 1rem;
|
||||
background-color: unset;
|
||||
color: var(--foreground-color);
|
||||
border-radius: 0.5rem 0;
|
||||
padding: 0.5rem 0.75rem;
|
||||
|
||||
&.primary {
|
||||
color: var(--button-fg-color);
|
||||
background-color: var(--button-background-color);
|
||||
border: 2px solid #8da9c4;
|
||||
|
||||
&:focus-within, &:hover {
|
||||
background-color: var(--button-hover-color);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: var(--button-active-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.ghost {
|
||||
&:hover, &:focus-within {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
23
src/components/atoms/Card.astro
Normal file
23
src/components/atoms/Card.astro
Normal file
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
interface Props {
|
||||
to: string;
|
||||
class?: string;
|
||||
}
|
||||
|
||||
const { to, class: className, ...rest } = Astro.props;
|
||||
---
|
||||
|
||||
<a class:list={["card", className]} href={to} {...rest}>
|
||||
<slot />
|
||||
</a>
|
||||
|
||||
<style>
|
||||
.card {
|
||||
background-color: var(--navigation-background-color);
|
||||
display: inline-block;
|
||||
padding: 1rem;
|
||||
border-radius: 0.25rem;
|
||||
max-width: 80vw;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
19
src/components/atoms/HorizontalSlider.astro
Normal file
19
src/components/atoms/HorizontalSlider.astro
Normal file
|
@ -0,0 +1,19 @@
|
|||
<div class="module-slider">
|
||||
<div class="slider-content">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.module-slider {
|
||||
overflow-x: auto;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.slider-content {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
flex-wrap: nowrap;
|
||||
overflow-y: visible;
|
||||
}
|
||||
</style>
|
|
@ -15,58 +15,34 @@ const currentPath = new URL(Astro.url).pathname.split('/')[1];
|
|||
a {
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
font-size: larger;
|
||||
font-size: large;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: "{";
|
||||
transform: translateX(-2rem);
|
||||
left: 0;
|
||||
position: absolute;
|
||||
transition-property: transform, opacity;
|
||||
transition-duration: 150ms;
|
||||
transition-timing-function: cubic-bezier(0.785, 0.135, 0.15, 0.86);
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "}";
|
||||
transform: translateX(2rem);
|
||||
right: 0;
|
||||
position: absolute;
|
||||
font-family: monospace;
|
||||
content: ".clickable";
|
||||
transition-property: transform, opacity;
|
||||
transition-duration: 150ms;
|
||||
transition-timing-function: cubic-bezier(0.785, 0.135, 0.15, 0.86);
|
||||
}
|
||||
|
||||
&:not(.current) {
|
||||
&::after,
|
||||
&::before {
|
||||
&::after {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus-within {
|
||||
&::before,
|
||||
&::after {
|
||||
opacity: 1;
|
||||
}
|
||||
&::before { transform: translateX(-1rem); }
|
||||
&::after { transform: translateX(1rem); }
|
||||
}
|
||||
}
|
||||
|
||||
&.current {
|
||||
&::before {
|
||||
transition: transform 100ms cubic-bezier(0.785, 0.135, 0.15, 0.86);
|
||||
transform: translateX(-2rem);
|
||||
}
|
||||
|
||||
&:hover::before,
|
||||
&:focus-visible::before {
|
||||
transform: translateX(-1rem);
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '.current';
|
||||
transform: translateX(2rem);
|
||||
transition: transform 100ms cubic-bezier(0.785, 0.135, 0.15, 0.86);
|
||||
}
|
||||
|
|
77
src/components/nav.astro
Normal file
77
src/components/nav.astro
Normal file
|
@ -0,0 +1,77 @@
|
|||
---
|
||||
import { Icon } from 'astro-icon/components';
|
||||
import Button from './atoms/Button.astro';
|
||||
import Link from './atoms/Link.astro';
|
||||
---
|
||||
|
||||
<div class="nav-wrapper">
|
||||
<Button className="nav-open">
|
||||
<Icon name="ham" />
|
||||
Menü
|
||||
</Button>
|
||||
</div>
|
||||
<nav aria-hidden="true" class="main">
|
||||
<Button className="nav-close" aria-label="Navigation schließen" type="ghost">
|
||||
Menü schließen
|
||||
</Button>
|
||||
<ul>
|
||||
<li><Link to="/">Startseite</Link></li>
|
||||
<li><Link to="/knowledge-base">Knowledge-Base</Link></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
function toggleMenu() {
|
||||
const targetAttr = 'aria-hidden';
|
||||
const nav = document.querySelector('nav.main') as HTMLElement;
|
||||
const nextState = nav.getAttribute(targetAttr) === 'true' ? 'false' : 'true';
|
||||
nav.setAttribute(targetAttr, nextState);
|
||||
}
|
||||
|
||||
const openbutton = document.querySelector('button.nav-open') as HTMLButtonElement;
|
||||
openbutton.addEventListener('click', toggleMenu);
|
||||
const closeButton = document.querySelector('button.nav-close') as HTMLButtonElement;
|
||||
closeButton.addEventListener('click', toggleMenu);
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
div.nav-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
nav.main {
|
||||
position: absolute;
|
||||
height: calc(100vh - 2rem);
|
||||
max-width: 90vw;
|
||||
width: 300px;
|
||||
top: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
transition: left 150ms ease-out;
|
||||
background-color: var(--navigation-background-color);
|
||||
border-right: 2px solid #8da9c4;
|
||||
padding-left: 2rem;
|
||||
padding-top: 2rem;
|
||||
}
|
||||
|
||||
nav.main ul {
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
line-height: 2.5rem;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
nav.main[aria-hidden="true"] {
|
||||
left: -100vw;
|
||||
}
|
||||
|
||||
nav.main[aria-hidden="false"] {
|
||||
left: 0rem;
|
||||
}
|
||||
|
||||
button.nav-open {
|
||||
display: inline-flex;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
5
src/icons/ham.svg
Normal file
5
src/icons/ham.svg
Normal file
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor">
|
||||
<rect width="16" height="2" y="3" rx="1"/>
|
||||
<rect width="16" height="2" y="7" rx="1" />
|
||||
<rect width="16" height="2" y="11" rx="1" />
|
||||
</svg>
|
After Width: | Height: | Size: 225 B |
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
import Link from '../components/atoms/Link.astro';
|
||||
import { getLangFromUrl, useTranslations } from '../i18n/utils';
|
||||
import Navigation from '../components/nav.astro'
|
||||
import { getLangFromUrl } from '../i18n/utils';
|
||||
import '../styles/global.css'
|
||||
|
||||
interface Props {
|
||||
|
@ -9,7 +9,7 @@ interface Props {
|
|||
|
||||
const { title } = Astro.props;
|
||||
const lang = getLangFromUrl(Astro.url);
|
||||
const t = useTranslations(lang);
|
||||
// const t = useTranslations(lang);
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
|
@ -24,10 +24,7 @@ const t = useTranslations(lang);
|
|||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav>
|
||||
<Link to="/">{t('nav.home')}</Link>
|
||||
<Link to="/else">{t('nav.knowledgeBase')}</Link>
|
||||
</nav>
|
||||
<Navigation />
|
||||
</header>
|
||||
<main>
|
||||
<slot />
|
||||
|
@ -35,23 +32,12 @@ const t = useTranslations(lang);
|
|||
</body>
|
||||
</html>
|
||||
<style is:global lang="scss">
|
||||
:root {
|
||||
--accent: 136, 58, 234;
|
||||
--accent-light: 224, 204, 250;
|
||||
--accent-dark: 49, 10, 101;
|
||||
--accent-gradient: linear-gradient(
|
||||
45deg,
|
||||
rgb(var(--accent)),
|
||||
rgb(var(--accent-light)) 30%,
|
||||
white 60%
|
||||
);
|
||||
}
|
||||
html {
|
||||
html, a:visited {
|
||||
font-family: system-ui, sans-serif;
|
||||
background: #13151a;
|
||||
color: white;
|
||||
background-color: var(--background-color);
|
||||
color: var(--foreground-color);
|
||||
}
|
||||
main {
|
||||
body {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
@ -66,11 +52,10 @@ const t = useTranslations(lang);
|
|||
Courier New,
|
||||
monospace;
|
||||
}
|
||||
nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4rem;
|
||||
margin: 1rem 0 2rem 0;
|
||||
header {
|
||||
margin: 1rem 1rem;
|
||||
}
|
||||
main {
|
||||
margin: 0 1rem;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
---
|
||||
import Layout from '../layouts/Layout.astro';
|
||||
import { useTranslations } from '../i18n/utils';
|
||||
import '../styles/homepage-markdown.scss';
|
||||
import { Icon } from 'astro-icon/components';
|
||||
|
||||
const t = useTranslations();
|
||||
|
|
68
src/pages/knowledge-base/index.astro
Normal file
68
src/pages/knowledge-base/index.astro
Normal file
|
@ -0,0 +1,68 @@
|
|||
---
|
||||
import { Icon } from 'astro-icon/components'
|
||||
import Card from '../../components/atoms/Card.astro'
|
||||
import HorizontalSlider from '../../components/atoms/HorizontalSlider.astro'
|
||||
import { getCollection } from 'astro:content'
|
||||
import Layout from '../../layouts/Layout.astro'
|
||||
|
||||
const dhbwModules = await getCollection('dhbw', (module) => module.data.show);
|
||||
---
|
||||
|
||||
<Layout title="Startseite der Knowledge-Base">
|
||||
<section>
|
||||
<h1>Startseite der Knowledge-Base</h1>
|
||||
<p>
|
||||
Hier findet Ihr verschiedene Einträge / Beiträge / innere Monologe jedweder Art von Wissen, die ich als Entwickler sammeln und teilen kann oder will. Die Inhalte sollten (im besten Fall) mit der Zeit mehr werden, eine Garantie "regelmäßig" etwas zu verfassen kann ich aber nicht geben.
|
||||
</p>
|
||||
<p>
|
||||
Zusätzlich zu den Inhalten werden hier auch Informationen aufbereitet, die ich als Dozent an der DHBW Karlsruhe in den Module Web Engineering I sowie Web Engineering II präsentiere.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>DHBW Module</h2>
|
||||
<p>
|
||||
Hier findet Ihr alles rund um die Module die ich als Dozent für die DHBW verfasst habe.
|
||||
</p>
|
||||
<HorizontalSlider>
|
||||
{dhbwModules.map((module) => (
|
||||
<Card to={`${module.data.staticPath}${module.slug}`} class="module-card">
|
||||
<span class="card-title">{module.data.title}</span>
|
||||
<Icon name="arrow" class="arrow" />
|
||||
</Card>
|
||||
))}
|
||||
</HorizontalSlider>
|
||||
</section>
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
.module-card {
|
||||
height: 5rem;
|
||||
display: inline-flex;
|
||||
min-width: 250px;
|
||||
justify-content: space-between;
|
||||
margin-right: 1rem;
|
||||
color: var(--foreground-color);
|
||||
border-bottom: 2px solid transparent;
|
||||
transition: border-bottom 100ms ease-in;
|
||||
}
|
||||
|
||||
.module-card:hover {
|
||||
border-bottom: 2px solid white;
|
||||
}
|
||||
|
||||
.module-card .arrow {
|
||||
--size: 2rem;
|
||||
border-radius: 50%;
|
||||
height: calc(var(--size) / 2);
|
||||
width: calc(var(--size) / 2);
|
||||
padding: calc(var(--size) / 3);
|
||||
background-color: var(--button-background-color);
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.module-card .card-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,11 @@
|
|||
:root {
|
||||
--background-color: #051923;
|
||||
--foreground-color: #eef4ed;
|
||||
|
||||
--navigation-background-color: #003554;
|
||||
--button-background-color: #0582ca;
|
||||
--button-background-color-translucent: #0582ca33;
|
||||
--button-hover-color: #006494;
|
||||
--button-active-color: #051923;
|
||||
--button-fg-color: white;
|
||||
}
|
7
src/utils/classes.ts
Normal file
7
src/utils/classes.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
export const clx = (c: Record<string, boolean>, additional?: string) => {
|
||||
const converted = Object.entries(c).map(([key, value]) => value ? key : null).filter((key) => !!key).join(' ');
|
||||
if (additional) {
|
||||
return `${converted} ${additional}`;
|
||||
}
|
||||
return converted;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue