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>
|
||||
<div class="inner">
|
||||
<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>
|
||||
</footer>
|
|
@ -71,6 +71,8 @@
|
|||
},
|
||||
"contact": {
|
||||
"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": {
|
||||
"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}>
|
||||
<header class="main under-nav">
|
||||
<div class="inner">
|
||||
<div class="grid">
|
||||
<div>
|
||||
<img src="/assets/logo.webp" class="logo">
|
||||
<h1 set:html={ t("home.header.title") }></h1>
|
||||
<p>{ t("home.header.description") }</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<section>
|
||||
<div class="inner">
|
||||
<div class="centered">
|
||||
<h2>{ t("home.services.title") }</h2>
|
||||
<p>{ t("home.services.description") }</p>
|
||||
</div>
|
||||
<div class="services">
|
||||
{ [...public_services, ...invite_services].slice(0, 6).map(service =>
|
||||
<Service {...service} />
|
||||
) }
|
||||
</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>
|
||||
</section>
|
||||
</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 { t } from "astro-i18n";
|
||||
|
||||
const meta = {
|
||||
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}>
|
||||
<header>
|
||||
<div class="inner">
|
||||
<h1>{ t("contact.title") }</h1>
|
||||
<p>email: <a href="mailto:hello@codespace.cz">hello@codespace.cz</a></p>
|
||||
<p>{ t("contact.description") }</p>
|
||||
</div>
|
||||
</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>
|
||||
|
|
|
@ -7,25 +7,12 @@
|
|||
|
||||
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 {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 */
|
||||
|
@ -49,3 +36,14 @@ footer > .inner {margin: 30px auto;}
|
|||
|
||||
|
||||
.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