commit
This commit is contained in:
108
frontend/src/components/ads/Drone/Drone.tsx
Normal file
108
frontend/src/components/ads/Drone/Drone.tsx
Normal file
@@ -0,0 +1,108 @@
|
||||
import React, { useEffect, useRef } from "react"
|
||||
import styles from "./drone.module.css"
|
||||
|
||||
export default function Drone() {
|
||||
const videoRef = useRef<HTMLVideoElement | null>(null)
|
||||
const sourceRef = useRef<HTMLSourceElement | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
function setVideoDroneQuality() {
|
||||
if (!sourceRef.current || !videoRef.current) return
|
||||
|
||||
const videoSources = {
|
||||
fullHD: "static/home/video/drone-background-video-1080p.mp4", // For desktops (1920x1080)
|
||||
hd: "static/home/video/drone-background-video-720p.mp4", // For tablets/smaller screens (1280x720)
|
||||
lowRes: "static/home/video/drone-background-video-480p.mp4" // For mobile devices or low performance (854x480)
|
||||
}
|
||||
|
||||
const screenWidth = window.innerWidth
|
||||
|
||||
// Pick appropriate source
|
||||
if (screenWidth >= 1920) {
|
||||
sourceRef.current.src =
|
||||
"https://vontor-cz.s3.eu-central-1.amazonaws.com/" + videoSources.fullHD
|
||||
} else if (screenWidth >= 1280) {
|
||||
sourceRef.current.src =
|
||||
"https://vontor-cz.s3.eu-central-1.amazonaws.com/" + videoSources.hd
|
||||
} else {
|
||||
sourceRef.current.src =
|
||||
"https://vontor-cz.s3.eu-central-1.amazonaws.com/" + videoSources.lowRes
|
||||
}
|
||||
|
||||
// Reload video
|
||||
videoRef.current.load()
|
||||
console.log("Drone video set!")
|
||||
}
|
||||
|
||||
// Run once on mount
|
||||
setVideoDroneQuality()
|
||||
|
||||
// Optional: rerun on resize
|
||||
window.addEventListener("resize", setVideoDroneQuality)
|
||||
return () => {
|
||||
window.removeEventListener("resize", setVideoDroneQuality)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className={`${styles.drone}`}>
|
||||
<video
|
||||
ref={videoRef}
|
||||
id="drone-video"
|
||||
className={styles.videoBackground}
|
||||
autoPlay
|
||||
muted
|
||||
loop
|
||||
playsInline
|
||||
>
|
||||
<source ref={sourceRef} id="video-source" type="video/mp4" />
|
||||
Your browser does not support video.
|
||||
</video>
|
||||
|
||||
<article>
|
||||
<header>
|
||||
<h1>Letecké snímky dronem</h1>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section>
|
||||
<h2>Oprávnění</h2>
|
||||
<p>
|
||||
A1, A2, A3 a průkaz na vysílačku!
|
||||
<br />
|
||||
Mohu garantovat bezpečný provoz dronu i ve složitějších podmínkách.
|
||||
Mám také možnost žádat o povolení k letu v blízkosti letišť!
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Cena</h2>
|
||||
<p>
|
||||
Nabízím letecké záběry dronem <br />
|
||||
za cenu <u>3 000 Kč</u>.
|
||||
</p>
|
||||
<p>
|
||||
Pokud se nacházíte v Ostravě, doprava je zdarma. Pro oblasti mimo Ostravu účtuji 10 Kč/km.
|
||||
</p>
|
||||
<p>
|
||||
Cena se může odvíjet ještě podle složitosti získaní povolení.*
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Výstup</h2>
|
||||
<p>
|
||||
Rád Vám připravím jednoduchý sestřih videa, který můžete rychle použít,
|
||||
nebo Vám mohu poskytnout samotné záběry k vlastní editaci.
|
||||
</p>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<div>
|
||||
V případě zájmu mě neváhejte <br />
|
||||
<a href="#contacts">kontaktovat!</a>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
103
frontend/src/components/ads/Drone/drone.module.css
Normal file
103
frontend/src/components/ads/Drone/drone.module.css
Normal file
@@ -0,0 +1,103 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
|
||||
|
||||
|
||||
|
||||
|
||||
.drone{
|
||||
margin-top: -4em;
|
||||
font-style: normal;
|
||||
|
||||
width: 100%;
|
||||
position: relative;
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
.drone .videoBackground {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
object-fit: cover;
|
||||
z-index: -1;
|
||||
|
||||
clip-path: polygon(0 3%, 15% 0, 30% 7%, 42% 3%, 61% 1%, 82% 5%, 100% 1%, 100% 94%, 82% 100%, 65% 96%, 47% 99%, 30% 90%, 14% 98%, 0 94%);
|
||||
}
|
||||
|
||||
|
||||
.drone article{
|
||||
padding: 5em;
|
||||
|
||||
display: flex;
|
||||
|
||||
border-radius: 2em;
|
||||
padding: 3em;
|
||||
gap: 2em;
|
||||
|
||||
position: relative;
|
||||
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
.drone article header h1{
|
||||
font-size: 4em;
|
||||
|
||||
font-weight: 300;
|
||||
}
|
||||
.drone article header{
|
||||
flex: 1;
|
||||
}
|
||||
.drone article main{
|
||||
width: 90%;
|
||||
display: flex;
|
||||
font-size: 1em;
|
||||
/* width: 60%; */
|
||||
flex: 2;
|
||||
flex-direction: row;
|
||||
|
||||
font-weight: 400;
|
||||
|
||||
gap: 2em;
|
||||
/* flex-wrap: wrap; */
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
.drone a{
|
||||
color: white;
|
||||
}
|
||||
.drone article div{
|
||||
display: flex;
|
||||
flex: 1;
|
||||
font-size: 1.25em;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
|
||||
@media only screen and (max-width: 990px) {
|
||||
.drone article header h1{
|
||||
font-size: 2.3em;
|
||||
|
||||
font-weight: 200;
|
||||
}
|
||||
.drone article header{
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.drone article main{
|
||||
flex-direction: column;
|
||||
font-size: 1em;
|
||||
}
|
||||
.drone article{
|
||||
height: auto;
|
||||
}
|
||||
.drone article div{
|
||||
margin: 2em;
|
||||
text-align: center;
|
||||
}
|
||||
.drone video{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
BIN
frontend/src/components/ads/Drone/readme.png
Normal file
BIN
frontend/src/components/ads/Drone/readme.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
164
frontend/src/components/ads/Portfolio/Portfolio.module.css
Normal file
164
frontend/src/components/ads/Portfolio/Portfolio.module.css
Normal file
@@ -0,0 +1,164 @@
|
||||
.portfolio {
|
||||
margin: auto;
|
||||
margin-top: 10em;
|
||||
width: 80%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: center;
|
||||
color: white;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.portfolio div .door {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: #c2a67d;
|
||||
color: #5e5747;
|
||||
|
||||
border-radius: 1em;
|
||||
|
||||
transform-origin: bottom;
|
||||
transition: transform 0.5s ease-in-out;
|
||||
|
||||
z-index: 3;
|
||||
|
||||
}
|
||||
.portfolio div span svg{
|
||||
font-size: 5em;
|
||||
cursor: pointer;
|
||||
animation: shake 0.4s ease-in-out infinite;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@keyframes shake {
|
||||
0% { transform: translateX(0); }
|
||||
25% { transform: translateX(-2px) rotate(-8deg); }
|
||||
50% { transform: translateX(2px) rotate(4deg); }
|
||||
75% { transform: translateX(-1px) rotate(-2deg); }
|
||||
100% { transform: translateX(0); }
|
||||
}
|
||||
|
||||
.door i{
|
||||
color: #5e5747;
|
||||
font-size: 5em;
|
||||
display: inline-block;
|
||||
animation: shake 0.4s ease-in-out infinite;
|
||||
animation-delay: 2s;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
.portfolio .door-open{
|
||||
transform: rotateX(180deg);
|
||||
}
|
||||
|
||||
.portfolio>header {
|
||||
width: fit-content;
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
top: -3.7em;
|
||||
left: 0;
|
||||
padding: 1em 3em;
|
||||
padding-bottom: 0;
|
||||
background-color: #cdc19c;
|
||||
color: #5e5747;
|
||||
border-top-left-radius: 1em;
|
||||
border-top-right-radius: 1em;
|
||||
}
|
||||
|
||||
.portfolio>header h1 {
|
||||
font-size: 2.5em;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.portfolio>header i {
|
||||
font-size: 6em;
|
||||
}
|
||||
|
||||
.portfolio article{
|
||||
position: relative;
|
||||
}
|
||||
.portfolio article::after{
|
||||
clip-path: polygon(0% 0%, 11% 12.5%, 0% 25%, 11% 37.5%, 0% 50%, 11% 62.5%, 0% 75%, 11% 87.5%, 0% 100%, 100% 100%, 84% 87.5%, 98% 75%, 86% 62.5%, 100% 50%, 86% 37.5%, 100% 25%, 93% 12.5%, 100% 0%);
|
||||
content: "";
|
||||
bottom: 0;
|
||||
right: -2em;
|
||||
|
||||
height: 2em;
|
||||
width: 6em;
|
||||
transform: rotate(-45deg);
|
||||
|
||||
position: absolute;
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.portfolio article::before{
|
||||
clip-path: polygon(0% 0%, 11% 12.5%, 0% 25%, 11% 37.5%, 0% 50%, 11% 62.5%, 0% 75%, 11% 87.5%, 0% 100%, 100% 100%, 84% 87.5%, 98% 75%, 86% 62.5%, 100% 50%, 86% 37.5%, 100% 25%, 93% 12.5%, 100% 0%);
|
||||
content: "";
|
||||
top: 0;
|
||||
left: -2em;
|
||||
|
||||
height: 2em;
|
||||
width: 6em;
|
||||
transform: rotate(-45deg);
|
||||
|
||||
position: absolute;
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.portfolio article header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
|
||||
.portfolio div {
|
||||
width: 100%;
|
||||
padding: 3em;
|
||||
background-color: #cdc19c;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
gap: 5em;
|
||||
|
||||
border-radius: 1em;
|
||||
border-top-left-radius: 0;
|
||||
}
|
||||
|
||||
.portfolio div article {
|
||||
display: flex;
|
||||
border-radius: 0em;
|
||||
background-color: #9c885c;
|
||||
width: 30%;
|
||||
text-align: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.portfolio div article header a img {
|
||||
padding: 2em 0;
|
||||
width: 80%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@media only screen and (max-width: 990px) {
|
||||
.portfolio div{
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.portfolio div article{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
66
frontend/src/components/ads/Portfolio/Portfolio.tsx
Normal file
66
frontend/src/components/ads/Portfolio/Portfolio.tsx
Normal file
@@ -0,0 +1,66 @@
|
||||
import React, { useState } from "react"
|
||||
import styles from "./Portfolio.module.css"
|
||||
import { LuMousePointerClick } from "react-icons/lu";
|
||||
|
||||
interface PortfolioItem {
|
||||
href: string
|
||||
src: string
|
||||
alt: string
|
||||
}
|
||||
|
||||
const portfolioItems: PortfolioItem[] = [
|
||||
{
|
||||
href: "https://davo1.cz",
|
||||
src: "/home/img/portfolio/DAVO_logo_2024_bile.png",
|
||||
alt: "davo1.cz logo",
|
||||
},
|
||||
{
|
||||
href: "https://perlica.cz",
|
||||
src: "/home/img/portfolio/perlica-3.webp",
|
||||
alt: "Perlica logo",
|
||||
},
|
||||
{
|
||||
href: "http://epinger2.cz",
|
||||
src: "/home/img/portfolio/logo_epinger.svg",
|
||||
alt: "Epinger2 logo",
|
||||
},
|
||||
]
|
||||
|
||||
export default function Portfolio() {
|
||||
const [doorOpen, setDoorOpen] = useState(false)
|
||||
|
||||
const toggleDoor = () => setDoorOpen((prev) => !prev)
|
||||
|
||||
return (
|
||||
<div className={styles.portfolio} id="portfolio">
|
||||
<header>
|
||||
<h1>Portfolio</h1>
|
||||
</header>
|
||||
|
||||
<div>
|
||||
|
||||
<span
|
||||
className={
|
||||
doorOpen
|
||||
? `${styles.door} ${styles["door-open"]}`
|
||||
: styles.door
|
||||
}
|
||||
onClick={toggleDoor}
|
||||
>
|
||||
<LuMousePointerClick/>
|
||||
</span>
|
||||
|
||||
{portfolioItems.map((item, index) => (
|
||||
<article key={index} className={styles.article}>
|
||||
<header>
|
||||
<a href={item.href} target="_blank" rel="noopener noreferrer">
|
||||
<img src={item.src} alt={item.alt} />
|
||||
</a>
|
||||
</header>
|
||||
<main></main>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
BIN
frontend/src/components/ads/Portfolio/readme.png
Normal file
BIN
frontend/src/components/ads/Portfolio/readme.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
0
frontend/src/components/auth/LogOut.tsx
Normal file
0
frontend/src/components/auth/LogOut.tsx
Normal file
0
frontend/src/components/auth/LoginForm.tsx
Normal file
0
frontend/src/components/auth/LoginForm.tsx
Normal file
Reference in New Issue
Block a user