1
0
Fork 0

feat: final commit

Signed-off-by: Vojtech Mares <iam@vojtechmares.com>
This commit is contained in:
Vojtěch Mareš 2023-12-13 18:20:21 +01:00
parent 517a25d91d
commit 7b5d149ecc
Signed by: vojtech.mares
GPG key ID: C6827B976F17240D
21 changed files with 463 additions and 100 deletions

View file

@ -0,0 +1,5 @@
{
"name": "content",
"version": "0.0.0",
"private": true
}

View file

@ -0,0 +1,11 @@
---
title: Kubernetes školení
slug: kubernetes
description: TODO
image: ../images/kubernetes.png
price:
open: 9000
corporate: 29000
days: 2
featured: true
---

View file

@ -0,0 +1,11 @@
---
title: Terraform školení
slug: terraform
description: TODO
image: ../images/terraform.png
price:
open: 5000
corporate: 19000
days: 1
featured: false
---

View file

View file

@ -1,4 +1,5 @@
import '/styles/global.css';
import { Footer } from 'components/Footer';
import 'styles/global.css';
import { Metadata } from 'next';
export const metadata: Metadata = {
@ -16,9 +17,10 @@ export default function RootLayout({
children: React.ReactNode;
}) {
return (
<html lang="en" className="[color-scheme:dark]">
<body className="bg-gray-1100 overflow-y-scroll bg-[url('/grid.svg')] pb-36">
<h1>Terraform Školení</h1>
<html lang="cs">
<body>
{children}
<Footer />
</body>
</html>
);

View file

@ -1,13 +0,0 @@
import { Boundary } from '../components/Boundary';
export default function NotFound() {
return (
<Boundary labels={['not-found.tsx']} color="pink">
<div className="space-y-4 text-vercel-pink">
<h2 className="text-lg font-bold">Not Found</h2>
<p className="text-sm">Could not find requested resource</p>
</div>
</Boundary>
);
}

View file

@ -1,5 +1,26 @@
import { Container } from "components/Container";
import { Hero } from "../components/Hero";
import { Dates } from "../components/Dates";
import { Price } from "../components/Price";
import { CourseDetails } from "components/CourseDetails";
export default function Page() {
return (
<>Hello</>
<>
<main>
<Hero />
<div className="bg-amber-500 h-8" />
{/* <Dates /> */}
<Container className="mt-12 md:grid md:grid-cols-5 md:gap-x-4 md:gap-y-4">
<div className="md:col-span-3">
<CourseDetails />
</div>
<div className="mt-8 md:col-span-2 md:mt-0">
<Price />
</div>
</Container>
</main>
</>
);
}

View file

@ -1,82 +0,0 @@
import clsx from 'clsx';
import React from 'react';
const Label = ({
children,
animateRerendering,
color,
}: {
children: React.ReactNode;
animateRerendering?: boolean;
color?: 'default' | 'pink' | 'blue' | 'violet' | 'cyan' | 'orange';
}) => {
return (
<div
className={clsx('rounded-full px-1.5 shadow-[0_0_1px_3px_black]', {
'bg-gray-800 text-gray-300': color === 'default',
'bg-vercel-pink text-white': color === 'pink',
'bg-vercel-blue text-white': color === 'blue',
'bg-vercel-cyan text-white': color === 'cyan',
'bg-vercel-violet text-violet-100': color === 'violet',
'bg-vercel-orange text-white': color === 'orange',
'animate-[highlight_1s_ease-in-out_1]': animateRerendering,
})}
>
{children}
</div>
);
};
export const Boundary = ({
children,
labels = ['children'],
size = 'default',
color = 'default',
animateRerendering = true,
}: {
children: React.ReactNode;
labels?: string[];
size?: 'small' | 'default';
color?: 'default' | 'pink' | 'blue' | 'violet' | 'cyan' | 'orange';
animateRerendering?: boolean;
}) => {
return (
<div
className={clsx('relative rounded-lg border border-dashed', {
'p-3 lg:p-5': size === 'small',
'p-4 lg:p-9': size === 'default',
'border-gray-700': color === 'default',
'border-vercel-pink': color === 'pink',
'border-vercel-blue': color === 'blue',
'border-vercel-cyan': color === 'cyan',
'border-vercel-violet': color === 'violet',
'border-vercel-orange': color === 'orange',
'animate-[rerender_1s_ease-in-out_1] text-vercel-pink':
animateRerendering,
})}
>
<div
className={clsx(
'absolute -top-2.5 flex gap-x-1 text-[9px] uppercase leading-4 tracking-widest',
{
'left-3 lg:left-5': size === 'small',
'left-4 lg:left-9': size === 'default',
},
)}
>
{labels.map((label) => {
return (
<Label
key={label}
color={color}
animateRerendering={animateRerendering}
>
{label}
</Label>
);
})}
</div>
{children}
</div>
);
};

View file

@ -0,0 +1,75 @@
import Link from "next/link";
import clsx from "clsx";
import { ReactNode } from "react";
const baseStyles = {
solid:
"group inline-flex items-center justify-center rounded-full font-semibold focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2",
outline:
"group inline-flex ring-1 items-center justify-center rounded-full focus:outline-none",
};
const variantStyles = {
solid: {
black:
"bg-black text-white hover:bg-slate-700 active:bg-slate-800 focus-visible:outline-slate-900",
amber:
"bg-amber-500 text-white hover:bg-amber-600 active:bg-amber-800 focus-visible:outline-amber-500",
white:
"bg-white text-black hover:bg-amber-50 active:bg-amber-200 focus-visible:outline-white",
},
outline: {
black:
"ring-slate-200 text-black hover:ring-slate-300 active:bg-slate-100 focus-visible:outline-amber-500 focus-visible:ring-slate-300",
white:
"ring-slate-700 text-white hover:ring-slate-500 active:ring-slate-700 focus-visible:outline-white",
amber: "", // Outline buttons cannot be amber
},
};
const transitionStyle = "transition duration-150 ease-in-out";
const sizeStyles = {
medium: "px-4 py-2 text-sm",
large: "px-8 py-4 text-base",
};
type Props = {
variant?: "solid" | "outline";
color?: "black" | "white" | "amber";
size?: "medium" | "large";
className?: string;
href?: string;
children?: ReactNode;
};
export function Button({
variant = "solid",
color = "black",
size = "medium",
className,
href,
children,
}: Props) {
if (variant === "outline" && color === "amber") {
throw new Error("Outline buttons cannot be amber");
}
className = clsx(
baseStyles[variant],
variantStyles[variant][color],
sizeStyles[size],
transitionStyle,
className
);
if (href !== undefined) {
return (
<Link href={href} className={className}>
{children}
</Link>
);
} else {
return <button className={className}>{children}</button>;
}
}

View file

@ -0,0 +1,15 @@
import clsx from "clsx";
import { ReactNode } from "react";
type Props = {
className?: string;
children?: ReactNode;
};
export function Container({ className, children }: Props) {
return (
<div className={clsx("mx-auto max-w-7xl px-4 sm:px-6 lg:px-8", className)}>
{children}
</div>
);
}

View file

@ -0,0 +1,44 @@
export function CourseDetails() {
return (
<>
<h1 className="text-2xl font-medium">Co to je Terraform a k čemu se používá?</h1>
<p className="text-slate-700">
Terraform je nástroj, který se používá ke správě infrastruktury v cloudu, jak veřejném (AWS, Azure, GCP), tak privátním (OpenStack, VMware vSphere).
Terraform Vám umožní spravovat infrastruktutru jako kód, to znamená verzovanou v Gitu, přidávání resources pomocí merge (pull) requestů a mnoho dalších výhod. Infrastrukturu můžete dále nasadit do testovacího prostředí přesně tak, jako je v produkci bez zbytečného úsilí. O všech komponentách máte přehled a můžete predikovat ceny. Konec klikání infrastruktury, zkuste Terraform.
Terraform umožnuje spravovat více cloudových providerů současne, zároveň umožnuje pracovat s hibridními cloudy (část v privátním cloudu, část ve veřejném).
</p>
<h1 className="text-2xl font-medium">Jak školení probíhá</h1>
<p className="text-slate-700">Školení je formou workshopu, všechno si podrobně vyzkoušíme a vysvětlíme. Ukážeme si jak Terraform pracuje, jak jej používat v teamu a jak jím spravovat infrastukturu. Uděláme si příklad infrastruktury jednoduché aplikace, kde nastavíme vše - od DNS, přes Kubernetes cluster po S3 file storage.</p>
<h1 className="text-2xl font-medium">Co Vás naučím</h1>
<ul>
<li className="my-0">Základní koncept Terraformu a "Infrastructure as Code"</li>
<li className="my-0">Výhody Terraformu proti Ansible, Puppetu, ...</li>
<li className="my-0">Konfigurace Terraformu pro práci v teamu</li>
<li className="my-0">Ovládání Terraform CLI</li>
<li className="my-0">Úvod do Terraform Configuration Language (HCL)</li>
<li className="my-0">Terraform Providers - napojení na cloudy</li>
<li className="my-0">Práce s resources v Terraformu</li>
<li className="my-0">Terraform moduly</li>
<li className="my-0">Best Practice</li>
</ul>
<h1 className="text-2xl font-medium">Pro koho je školení určeno</h1>
<p className="text-slate-700">Školení je určeno pro DevOps a adminy, kteří chtějí lépe a efektivněji spravovat infrastrukturu. Zároveň také pro vývojáře, kteří se starají o nejakou infrastrukturu v cloudech.</p>
<h1 className="text-2xl font-medium">Předchozí znalosti</h1>
<ul>
<li className="my-0">Základní znalost veřejných cloudů (AWS, DigitalOcean, Azure, ...)</li>
<li className="my-0">Základy práce v terminálu</li>
</ul>
<h1 className="text-2xl font-medium">Technické požadavky</h1>
<ul>
<li className="my-0">Nainstalovaný Terraform</li>
<li className="my-0">Přístup na internet (ideálně bez korporatni proxy)</li>
<li className="my-0">Vlastní účet v DigitalOceanu výhodou</li>
</ul>
</>
);
}

View file

@ -0,0 +1,35 @@
export function Dates() {
return (
<div className="mt-8 mx-auto max-w-3xl px-4 sm:px-6 lg:px-8">
<h2 className="text-4xl">Veřejné termíny</h2>
<div className="mt-8 flow-root">
<div className="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div className="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
<table className="min-w-full divide-y divide-gray-300">
<thead>
<tr>
<th scope="col" className="py-3.5 pl-4 pr-3 text-left font-semibold text-gray-900 sm:pl-0">Místo</th>
<th scope="col" className="px-3 py-3.5 text-left font-semibold text-gray-900">Datum</th>
<th scope="col" className="px-3 py-3.5 text-left font-semibold text-gray-900">Volná místa?</th>
<th scope="col" className="relative py-3.5 pl-3 pr-4 sm:pr-0">
<span className="sr-only">Registrovat</span>
</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200">
<tr>
<td className="whitespace-nowrap py-4 pl-4 pr-3 font-medium text-gray-900 sm:pl-0">Praha</td>
<td className="whitespace-nowrap px-3 py-4 text-gray-500">30. května 2023</td>
<td className="whitespace-nowrap px-3 py-4 text-gray-500">Ano</td>
<td className="relative whitespace-nowrap py-4 pl-3 pr-4 text-right font-medium sm:pr-0">
<a href="#" className="underline">Registrovat<span className="sr-only">, na termín školení</span></a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
)
}

View file

@ -0,0 +1,159 @@
import Link from "next/link";
import { Container } from "./Container";
import { Button } from "./Button";
export function Footer() {
return (
<footer className="bg-slate-50">
<Container className="py-8">
<div className="py-4">
<div className="grid grid-cols-1 gap-y-6 lg:grid-cols-4 lg:gap-4">
<div>
<h4 className="text-lg font-medium">Vojtěch Mareš</h4>
<ul className="mt-4 list-none">
<li>
<Link href="tel:+420732490651" className="underline">
+420 732 490 651
</Link>
</li>
<li>
<Link
href="mailto:iam@vojtechmares.com"
className="underline"
>
iam@vojtechmares.com
</Link>
</li>
<li className="mt-4">
Company ID
<br />
<code id="company-id">06999280</code>
</li>
<li className="mt-2">
VAT ID
<br />
<code id="vat-id">CZ9709180063</code>
</li>
</ul>
</div>
<div>
<h3 className="text-lg font-medium">Další školení</h3>
<ul className="mt-4 list-disc pl-4">
<li>
<Link href="https://www.vojtechmares.com/skoleni/kubernetes" className="underline">
Kubernetes
</Link>
</li>
<li>
<Link href="https://www.vojtechmares.com/skoleni/git" className="underline">Git</Link>
</li>
<li>
<Link href="https://www.vojtechmares.com/skoleni/terraform" className="underline">
Terraform
</Link>
</li>
<li>
<Link href="https://www.vojtechmares.com/skoleni/argocd" className="underline">ArgoCD</Link>
</li>
</ul>
</div>
<div>
<h3 className="text-lg font-medium">Důležité odkazy</h3>
<ul className="mt-4 list-disc pl-4">
<li>
<Link
href="https://vojtechmares.com/?utm_source=microsite&utm_medium=terraform-skoleni.cz&utm_content=link"
className="underline"
>
vojtechmares.com
</Link>
</li>
<li>
<Link
href="https://skoleni.io/?utm_source=vojtechmares&utm_medium=vojtechmares-com-website&utm_content=link"
className="underline"
target="_blank"
>
Skoleni.io
</Link>
</li>
<li>
<Link
href="https://devopsaci.cz/?utm_source=vojtechmares&utm_medium=vojtechmares-com-website&utm_content=link"
className="underline"
target="_blank"
>
DevOpsaci.cz
</Link>
</li>
</ul>
</div>
<div>
<h3 className="text-lg font-medium">Máte zájem o školení?</h3>
<p className="mt-4">
TBD.
</p>
<Button
href="mailto:iam@vojtechmares.com"
className="mt-5"
>
Napište mi
</Button>
</div>
</div>
</div>
<div className="flex flex-col items-center border-t border-slate-400/10 py-10 sm:flex-row-reverse sm:justify-between">
<div className="flex gap-x-6">
<Link
href="https://www.linkedin.com/in/vojtech-mares/"
target="_blank"
className="group"
aria-label="Vojtěch Mareš na LinkedIn"
>
<svg
// role="img"
// viewBox="0 0 24 24"
// xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
className="h-6 w-6 fill-black group-hover:fill-slate-700"
>
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" />
</svg>
</Link>
<Link
href="https://twitter.com/vojtechmares_"
target="_blank"
className="group"
aria-label="Vojtěch Mareš na Twitter"
>
<svg
aria-hidden="true"
className="h-6 w-6 fill-black group-hover:fill-slate-700"
>
<path d="M8.29 20.251c7.547 0 11.675-6.253 11.675-11.675 0-.178 0-.355-.012-.53A8.348 8.348 0 0 0 22 5.92a8.19 8.19 0 0 1-2.357.646 4.118 4.118 0 0 0 1.804-2.27 8.224 8.224 0 0 1-2.605.996 4.107 4.107 0 0 0-6.993 3.743 11.65 11.65 0 0 1-8.457-4.287 4.106 4.106 0 0 0 1.27 5.477A4.073 4.073 0 0 1 2.8 9.713v.052a4.105 4.105 0 0 0 3.292 4.022 4.093 4.093 0 0 1-1.853.07 4.108 4.108 0 0 0 3.834 2.85A8.233 8.233 0 0 1 2 18.407a11.615 11.615 0 0 0 6.29 1.84" />
</svg>
</Link>
<Link
href="https://github.com/vojtechmares"
target="_blank"
className="group"
aria-label="Vojtěch Mareš na GitHub"
>
<svg
aria-hidden="true"
className="h-6 w-6 fill-black group-hover:fill-slate-700"
>
<path d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0 1 12 6.844a9.59 9.59 0 0 1 2.504.337c1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.02 10.02 0 0 0 22 12.017C22 6.484 17.522 2 12 2Z" />
</svg>
</Link>
</div>
<p className="mt-6 text-slate-700 sm:mt-0">
Copyright &copy; {new Date().getFullYear()} Vojtěch Mareš. Všechna
práva vyhrazena.
</p>
</div>
</Container>
</footer>
);
}

View file

@ -0,0 +1,34 @@
import Image from 'next/image';
import clsx from 'clsx';
import { Container } from './Container';
import terraformLogo from '../images/terraform.svg';
export function Hero() {
return (
<>
<div className="bg-black pt-16 pb-16">
<Container className="flex flex-col justify-center md:flex-row md:justify-around md:items-end">
<Image
src={terraformLogo}
width="1500"
height="1500"
alt=""
priority
className={clsx(
"h-32 w-32",
terraformLogo.src.endsWith(".svg") ? "invert" : "rounded-full"
)}
/>
<div className="self-center">
<h1 className="text-center font-display text-5xl font-medium tracking-tight text-white sm:text-7xl leading-10">
Terraform školení
</h1>
<p className="mt-6 max-w-xl text-xl tracking-tight text-slate-100">
Školí: Vojtěch Mareš - DevOps konzultant, lektor a mentor
</p>
</div>
</Container>
</div>
</>
);
}

View file

@ -0,0 +1,45 @@
import { Button } from "./Button"
export function Price() {
return (
<>
<div className="mt-8 overflow-hidden rounded-lg bg-slate-50 shadow md:mt-0">
<div className="px-4 pt-5 sm:px-6">
<h3 className="text-lg font-medium leading-6 text-black">
Cena za školení
</h3>
</div>
<div className=" px-4 pb-5 pt-2">
<dl className="sm:divide-y sm:divide-slate-400">
<div className="py-4 sm:grid sm:grid-cols-2 sm:gap-4 sm:py-5 sm:px-6">
<dt className="font-medium text-slate-700">
Veřejný termín
</dt>
<dd className="mt-1 text-black sm:mt-0">
5500 CZK bez DPH
</dd>
</div>
<div className="py-4 sm:grid sm:grid-cols-2 sm:gap-4 sm:py-5 sm:px-6">
<dt className="font-medium text-slate-700">
Firemní školení
</dt>
<dd className="mt-1 text-black sm:mt-0">
19 000 CZK bez DPH
</dd>
</div>
</dl>
</div>
</div>
<div className="mt-8">
<Button
variant="solid"
color="amber"
className="w-full text-lg font-medium"
href="mailto:iam@vojtechmares.com"
>
Nezávazně poptat
</Button>
</div>
</>
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View file

@ -0,0 +1 @@
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Terraform</title><path d="M1.44 0v7.575l6.561 3.79V3.787zm21.12 4.227l-6.561 3.791v7.574l6.56-3.787zM8.72 4.23v7.575l6.561 3.787V8.018zm0 8.405v7.575L15.28 24v-7.578z"/></svg>

After

Width:  |  Height:  |  Size: 253 B