style changes
This commit is contained in:
@@ -1,99 +0,0 @@
|
||||
/*TODO: Implement the contact form functionality*/
|
||||
|
||||
{% load static %}
|
||||
|
||||
|
||||
|
||||
<div class="contact-me">
|
||||
<div class="opening">
|
||||
<i class="fa-solid fa-arrow-pointer" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="content">
|
||||
<form method="post" id="contactme-form">
|
||||
{% csrf_token %}
|
||||
{{ contactme_form }}
|
||||
<input type="submit" value="Submit">
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<div class="cover"></div>
|
||||
<div class="triangle"></div>
|
||||
|
||||
</div>
|
||||
<script src="{% static 'home/js/global/contact-me.js' %}"></script>
|
||||
|
||||
|
||||
contact-me.js:
|
||||
|
||||
$(document).ready(function () {
|
||||
$("#contactme-form").submit(function (event) {
|
||||
event.preventDefault(); // Prevent normal form submission
|
||||
|
||||
$.ajax({
|
||||
url: "/submit-contactme/", // URL of the Django view
|
||||
type: "POST",
|
||||
data: $(this).serialize(), // Serialize form data
|
||||
success: function (response) {
|
||||
if (response.success) {
|
||||
close_contact();
|
||||
|
||||
$("#contactme-form .success-form-alert").fadeIn();
|
||||
$("#contactme-form")[0].reset(); // Clear the form
|
||||
|
||||
alert("Zpráva odeslaná!")
|
||||
}
|
||||
},
|
||||
error: function (response) {
|
||||
alert("Zpráva nebyla odeslaná, zkontrolujte si připojení k internetu nebo naskytl u nás problém :(")
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$("#contactme-form .success-form .close").click(function () {
|
||||
$("#contactme-form .success-form-alert").fadeOut();
|
||||
});
|
||||
|
||||
var opened_contact = false;
|
||||
|
||||
$(document).on("click", ".contact-me .opening", function () {
|
||||
console.log("toggle mail");
|
||||
|
||||
const opening = $(".contact-me .opening");
|
||||
|
||||
|
||||
|
||||
|
||||
// Check if we're opening or closing
|
||||
if (opened_contact === false) {
|
||||
// Toggle rotation
|
||||
opening.toggleClass('rotate-opening');
|
||||
|
||||
// Wait for the rotation to finish
|
||||
setTimeout(function() {
|
||||
$(".contact-me .content").addClass('content-moveup-index');
|
||||
}, 500);
|
||||
|
||||
setTimeout(function() {
|
||||
$(".contact-me .content")[0].offsetHeight;
|
||||
|
||||
$(".contact-me .content").addClass('content-moveup');
|
||||
}, 1000); // Small delay to trigger transition
|
||||
|
||||
opened_contact = true;
|
||||
} else {
|
||||
close_contact();
|
||||
}
|
||||
});
|
||||
|
||||
function close_contact(){
|
||||
$(".contact-me .content").removeClass('content-moveup');
|
||||
|
||||
setTimeout(function() {
|
||||
$(".contact-me .content").toggleClass('content-moveup-index');
|
||||
$(".contact-me .opening").toggleClass('rotate-opening');
|
||||
}, 700);
|
||||
|
||||
opened_contact = false;
|
||||
}
|
||||
});
|
||||
@@ -1,82 +1,64 @@
|
||||
import React, { useState } from "react"
|
||||
import React, { useState, useRef } from "react"
|
||||
import styles from "./contact-me.module.css"
|
||||
|
||||
interface ContactFormResponse {
|
||||
success: boolean
|
||||
[key: string]: any
|
||||
}
|
||||
import { LuMousePointerClick } from "react-icons/lu";
|
||||
|
||||
export default function ContactMeForm() {
|
||||
const [opened, setOpened] = useState(false)
|
||||
const [formData, setFormData] = useState({ message: "", email: "" })
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [contentMoveUp, setContentMoveUp] = useState(false)
|
||||
const [openingBehind, setOpeningBehind] = useState(false)
|
||||
const [success, setSuccess] = useState(false)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const openingRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
function handleSubmit() {
|
||||
// form submission logic here
|
||||
}
|
||||
|
||||
const toggleOpen = () => {
|
||||
setOpened((prev) => !prev)
|
||||
}
|
||||
|
||||
const handleChange = (
|
||||
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
|
||||
) => {
|
||||
const { name, value } = e.target
|
||||
setFormData((prev) => ({ ...prev, [name]: value }))
|
||||
}
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
|
||||
try {
|
||||
const response = await fetch("/submit-contactme/", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-CSRFToken": getCSRFToken(),
|
||||
},
|
||||
body: JSON.stringify(formData),
|
||||
})
|
||||
|
||||
const data: ContactFormResponse = await response.json()
|
||||
|
||||
if (data.success) {
|
||||
setSuccess(true)
|
||||
setFormData({ message: "", email: "" })
|
||||
} else {
|
||||
setError("Zpráva nebyla odeslaná.")
|
||||
}
|
||||
} catch (err) {
|
||||
setError("Chyba připojení nebo serveru.")
|
||||
} finally {
|
||||
setLoading(false)
|
||||
if (!opened) {
|
||||
setOpened(true)
|
||||
setOpeningBehind(false)
|
||||
setContentMoveUp(false)
|
||||
// Wait for the rotate-opening animation to finish before moving content up
|
||||
// The actual moveUp will be handled in onTransitionEnd
|
||||
} else {
|
||||
setContentMoveUp(false)
|
||||
setOpeningBehind(false)
|
||||
setTimeout(() => setOpened(false), 1000) // match transition duration
|
||||
}
|
||||
}
|
||||
|
||||
// Utility to read CSRF token from cookies (Django)
|
||||
const getCSRFToken = (): string => {
|
||||
const match = document.cookie.match(/csrftoken=([^;]+)/)
|
||||
return match ? match[1] : ""
|
||||
const handleTransitionEnd = (e: React.TransitionEvent<HTMLDivElement>) => {
|
||||
if (opened && e.propertyName === "transform") {
|
||||
setContentMoveUp(true)
|
||||
// Move the opening behind after the animation
|
||||
setTimeout(() => setOpeningBehind(true), 10)
|
||||
}
|
||||
if (!opened && e.propertyName === "transform") {
|
||||
setOpeningBehind(false)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles["contact-me"]}>
|
||||
<div
|
||||
ref={openingRef}
|
||||
className={
|
||||
opened
|
||||
? `${styles.opening} ${styles["rotate-opening"] || ""}`
|
||||
: styles.opening
|
||||
[
|
||||
styles.opening,
|
||||
opened ? styles["rotate-opening"] : "",
|
||||
openingBehind ? styles["opening-behind"] : ""
|
||||
].filter(Boolean).join(" ")
|
||||
}
|
||||
onClick={toggleOpen}
|
||||
onTransitionEnd={handleTransitionEnd}
|
||||
>
|
||||
<i className="fa-solid fa-arrow-pointer" aria-hidden="true"></i>
|
||||
<LuMousePointerClick/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={
|
||||
opened
|
||||
? `${styles.content} ${styles["content-moveup"] || ""}`
|
||||
contentMoveUp
|
||||
? `${styles.content} ${styles["content-moveup"]}`
|
||||
: styles.content
|
||||
}
|
||||
>
|
||||
@@ -85,27 +67,15 @@ export default function ContactMeForm() {
|
||||
type="email"
|
||||
name="email"
|
||||
placeholder="Váš email"
|
||||
value={formData.email}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
<textarea
|
||||
name="message"
|
||||
placeholder="Vaše zpráva"
|
||||
value={formData.message}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
<input type="submit" value={loading ? "Odesílám..." : "Odeslat"} />
|
||||
<input type="submit"/>
|
||||
</form>
|
||||
|
||||
{success && (
|
||||
<div className={styles.successFormAlert}>
|
||||
<span>Zpráva odeslaná!</span>
|
||||
<button onClick={() => setSuccess(false)}>×</button>
|
||||
</div>
|
||||
)}
|
||||
{error && <div className={styles.errorFormAlert}>{error}</div>}
|
||||
</div>
|
||||
|
||||
<div className={styles.cover}></div>
|
||||
|
||||
@@ -35,6 +35,11 @@
|
||||
transform: rotateX(180deg);
|
||||
}
|
||||
|
||||
.opening svg{
|
||||
margin: auto;
|
||||
font-size: 3em;
|
||||
margin-top: -0.5em;
|
||||
}
|
||||
|
||||
|
||||
.contact-me .content {
|
||||
@@ -89,7 +94,7 @@
|
||||
|
||||
}
|
||||
|
||||
|
||||
.opening-behind { z-index: 0 !important; }
|
||||
|
||||
.contact-me .cover {
|
||||
position: absolute;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState } from "react"
|
||||
import styles from "./HomeNav.module.css"
|
||||
import { FaBars } from "react-icons/fa";
|
||||
|
||||
export default function HomeNav() {
|
||||
const [navOpen, setNavOpen] = useState(false)
|
||||
@@ -8,11 +9,7 @@ export default function HomeNav() {
|
||||
|
||||
return (
|
||||
<nav className={styles.nav}>
|
||||
<i
|
||||
id="toggle-nav"
|
||||
className={`fa-solid fa-bars ${styles.toggle}`}
|
||||
onClick={toggleNav}
|
||||
></i>
|
||||
<FaBars className={styles.toggle} onClick={toggleNav} />
|
||||
|
||||
<ul className={`${styles.navList} ${navOpen ? styles.open : ""}`}>
|
||||
<li id="nav-logo" className={styles.logo}>
|
||||
|
||||
Reference in New Issue
Block a user