Improved home & contact page + footer
This commit is contained in:
parent
4006cd3941
commit
342fc80734
8 changed files with 157 additions and 29 deletions
15
src/components/EmailLink.astro
Normal file
15
src/components/EmailLink.astro
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
interface Props {
|
||||||
|
email: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const { email } = Astro.props;
|
||||||
|
|
||||||
|
function getMailtoLink(email: string) {
|
||||||
|
return "mailto:" + email.split('').map(char => `&#${char.charCodeAt(0)};`).join('');
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
<Fragment set:html={`<a href="${getMailtoLink(email)}">`} />
|
||||||
|
<slot />
|
||||||
|
<Fragment set:html={`</a>`} />
|
53
src/components/Emcrypt.astro
Normal file
53
src/components/Emcrypt.astro
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
---
|
||||||
|
interface Props {
|
||||||
|
email: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const { email } = Astro.props;
|
||||||
|
|
||||||
|
function generate(mail: string) {
|
||||||
|
let segments = randomSplit(mail), arr = [];
|
||||||
|
let i = 0;
|
||||||
|
while (segments.length) {
|
||||||
|
if ((i-2)%5 == 0 || (i)%2 == 0) arr.push(randAlphabet());
|
||||||
|
else arr.push(segments.shift());
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function randomSplit(input: string) {
|
||||||
|
let segments = [];
|
||||||
|
while (input.length > 0) {
|
||||||
|
const segmentLength = Math.floor(Math.random() * 3) + 1;
|
||||||
|
segments.push(input.slice(0, segmentLength));
|
||||||
|
input = input.slice(segmentLength);
|
||||||
|
}
|
||||||
|
return segments;
|
||||||
|
}
|
||||||
|
|
||||||
|
function randAlphabet() {
|
||||||
|
let c = Math.floor(Math.random() * 3) + 1;
|
||||||
|
let chars = [];
|
||||||
|
for (let i = 0; i < c; i++) {
|
||||||
|
let rcc = Math.floor(Math.random() * 26) + 97;
|
||||||
|
chars.push(String.fromCharCode(rcc));
|
||||||
|
}
|
||||||
|
return chars.join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
const parts = generate(email);
|
||||||
|
---
|
||||||
|
|
||||||
|
<span class="emcrypt">
|
||||||
|
{ parts.map(part =>
|
||||||
|
<span>{ part }</span>
|
||||||
|
) }
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<style is:global>
|
||||||
|
|
||||||
|
.emcrypt *:nth-child(2n+1) {user-select: none; font-size: 0;}
|
||||||
|
.emcrypt *:nth-child(5n+3) {display: none;}
|
||||||
|
|
||||||
|
</style>
|
|
@ -1,5 +1,17 @@
|
||||||
|
---
|
||||||
|
import { Icon } from "astro-icon/components";
|
||||||
|
---
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
© CodeSpace { new Date().getFullYear() }
|
<div>
|
||||||
|
© CodeSpace { new Date().getFullYear() }
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a href="https://git.cdsp.cz/CodeSpace/Web" target="_blank">
|
||||||
|
<Icon name="tabler:code" />
|
||||||
|
Zdroj
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
@ -71,6 +71,8 @@
|
||||||
},
|
},
|
||||||
"contact": {
|
"contact": {
|
||||||
"title": "Kontakt",
|
"title": "Kontakt",
|
||||||
"description": "Způsoby, kterými nás můžete kontaktovat."
|
"description": "Způsoby, kterými nás můžete kontaktovat.",
|
||||||
|
"email": "Hlavní e-mail",
|
||||||
|
"noc": "Vše, co nepočká"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -71,6 +71,8 @@
|
||||||
},
|
},
|
||||||
"contact": {
|
"contact": {
|
||||||
"title": "Contact",
|
"title": "Contact",
|
||||||
"description": "Ways you can contact us."
|
"description": "Ways you can contact us.",
|
||||||
|
"email": "Main email address",
|
||||||
|
"noc": "Important things"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,24 +13,49 @@ const meta = {
|
||||||
<Layout meta={meta}>
|
<Layout meta={meta}>
|
||||||
<header class="main under-nav">
|
<header class="main under-nav">
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<div class="grid">
|
<div>
|
||||||
<div>
|
<img src="/assets/logo.webp" class="logo">
|
||||||
<h1 set:html={ t("home.header.title") }></h1>
|
<h1 set:html={ t("home.header.title") }></h1>
|
||||||
<p>{ t("home.header.description") }</p>
|
<p>{ t("home.header.description") }</p>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<section>
|
<section>
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<h2>{ t("home.services.title") }</h2>
|
<div class="centered">
|
||||||
<p>{ t("home.services.description") }</p>
|
<h2>{ t("home.services.title") }</h2>
|
||||||
|
<p>{ t("home.services.description") }</p>
|
||||||
|
</div>
|
||||||
<div class="services">
|
<div class="services">
|
||||||
{ [...public_services, ...invite_services].slice(0, 6).map(service =>
|
{ [...public_services, ...invite_services].slice(0, 6).map(service =>
|
||||||
<Service {...service} />
|
<Service {...service} />
|
||||||
) }
|
) }
|
||||||
</div>
|
</div>
|
||||||
<p set:html={ t("home.services.more", {link: l("/sluzby")}) }></p>
|
<p class="centered" set:html={ t("home.services.more", {link: l("/sluzby")}) }></p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
|
<style is:global>
|
||||||
|
|
||||||
|
header.main {background-image: radial-gradient(700px at 50% 130%, #d1205988, transparent);}
|
||||||
|
|
||||||
|
header.main h1 {font-weight: 900;}
|
||||||
|
header.main h1 span:nth-child(1) {color: var(--brand-color-1);}
|
||||||
|
header.main h1 span:nth-child(2) {color: var(--brand-color-2);}
|
||||||
|
|
||||||
|
header.main .logo {max-width: 70px;}
|
||||||
|
|
||||||
|
.services {text-align: center;}
|
||||||
|
.services :is(.title, .bottom) {justify-content: center;}
|
||||||
|
|
||||||
|
@media screen and (max-width: 650px) {
|
||||||
|
header.main h1 {font-size: 30px;}
|
||||||
|
header.main .logo {max-width: 50px;}
|
||||||
|
}
|
||||||
|
|
||||||
|
header.main .inner {max-width: 700px; text-align: center; margin: 100px auto;}
|
||||||
|
|
||||||
|
.centered {text-align: center;}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
|
@ -1,18 +1,39 @@
|
||||||
---
|
---
|
||||||
|
import { Icon } from 'astro-icon/components';
|
||||||
|
import EmailLink from '../components/EmailLink.astro';
|
||||||
|
import Emcrypt from '../components/Emcrypt.astro';
|
||||||
import Layout from '../layouts/Layout.astro';
|
import Layout from '../layouts/Layout.astro';
|
||||||
import { t } from "astro-i18n";
|
import { t } from "astro-i18n";
|
||||||
|
|
||||||
const meta = {
|
const meta = {
|
||||||
title: t("contact.title"),
|
title: t("contact.title"),
|
||||||
desc: t("contact.desc")
|
desc: t("contact.description")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const emails = [
|
||||||
|
{icon: "tabler:at", title: "contact.email", email: "hello@codespace.cz"},
|
||||||
|
{icon: "tabler:headset", title: "contact.noc", email: "noc@codespace.cz"}
|
||||||
|
];
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout meta={meta}>
|
<Layout meta={meta}>
|
||||||
<header>
|
<header>
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<h1>{ t("contact.title") }</h1>
|
<h1>{ t("contact.title") }</h1>
|
||||||
<p>email: <a href="mailto:hello@codespace.cz">hello@codespace.cz</a></p>
|
<p>{ t("contact.description") }</p>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
<section>
|
||||||
|
<div class="inner contacts">
|
||||||
|
{ emails.map(item =>
|
||||||
|
<EmailLink email={ item.email }>
|
||||||
|
<Icon name={ item.icon } />
|
||||||
|
<div>
|
||||||
|
<div class="title">{ t(item.title) }</div>
|
||||||
|
<Emcrypt email={ item.email } />
|
||||||
|
</div>
|
||||||
|
</EmailLink>
|
||||||
|
) }
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
|
@ -7,25 +7,12 @@
|
||||||
|
|
||||||
header.centered {text-align: center;}
|
header.centered {text-align: center;}
|
||||||
|
|
||||||
header.main {background-image: radial-gradient(max(50vh, 60vw) at -30vw 70vh, var(--brand-color-2), transparent), radial-gradient(max(50vh, 60vw) at 110vw -10vh, var(--brand-color-1), transparent); background-color: #000;}
|
|
||||||
|
|
||||||
header.main .grid {display: grid; grid-template-columns: 600px 1fr;}
|
|
||||||
|
|
||||||
header.main h1 {font-weight: 900; font-size: 40px;}
|
|
||||||
header.main h1 span:nth-child(1) {color: var(--brand-color-1);}
|
|
||||||
header.main h1 span:nth-child(2) {color: var(--brand-color-2);}
|
|
||||||
|
|
||||||
@media screen and (max-width: 650px) {
|
|
||||||
header.main > .inner {margin: 50px auto; text-wrap: balance; text-align: center;}
|
|
||||||
header.main .grid {grid-template-columns: 1fr;}
|
|
||||||
header.main h1 {font-size: 30px;}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Footer */
|
/* Footer */
|
||||||
|
|
||||||
footer {border-top: 1px solid var(--border-color);}
|
footer {border-top: 1px solid var(--border-color);}
|
||||||
footer > .inner {margin: 30px auto;}
|
footer > .inner {margin: 30px auto; display: flex; justify-content: space-between;}
|
||||||
|
footer a {text-decoration: none; display: flex; align-items: center; gap: 7px;}
|
||||||
|
|
||||||
|
|
||||||
/* Services */
|
/* Services */
|
||||||
|
@ -49,3 +36,14 @@ footer > .inner {margin: 30px auto;}
|
||||||
|
|
||||||
|
|
||||||
.label {padding: 2px 10px; background-color: var(--alt-bg-color); border-radius: 50px;}
|
.label {padding: 2px 10px; background-color: var(--alt-bg-color); border-radius: 50px;}
|
||||||
|
|
||||||
|
|
||||||
|
/* Contact */
|
||||||
|
|
||||||
|
.contacts {display: flex; flex-direction: column; gap: 20px;}
|
||||||
|
.contacts > a {display: flex; align-items: center; gap: 20px; text-decoration: none;}
|
||||||
|
.contacts > a > div {display: flex; flex-direction: column; gap: 8px; line-height: 1;}
|
||||||
|
|
||||||
|
.contacts svg {font-size: 34px; background-color: var(--alt-bg-color); border-radius: 100%; padding: 15px;}
|
||||||
|
.contacts .title {color: var(--title-color); font-size: 16px; text-transform: uppercase; letter-spacing: 1px; font-weight: 700;}
|
||||||
|
.contacts .emcrypt {font-size: 24px;}
|
||||||
|
|
Loading…
Reference in a new issue