diff --git a/src/components/mainViews/Contact.jsx b/src/components/mainViews/Contact.jsx index 43fea43..5822bb8 100644 --- a/src/components/mainViews/Contact.jsx +++ b/src/components/mainViews/Contact.jsx @@ -1,9 +1,60 @@ -import React from 'react' +import React from "react"; +import "../../css/Home.css"; +import LangSelect from "../LangSelect"; +import Mail from "../Mail"; +import Switch from "../Switch"; +import Navigation from "../Navigation"; +import LinkedInIcon from "../../assets/icons/socials/linkedin.svg?react"; +import GitHubIcon from "../../assets/icons/socials/square-github.svg?react"; +import Location from "../Location"; +import "animate.css"; +import { useState } from "react"; +import "../../css/GridContainer.css"; +import ContactTile from "../subComponents/Contact/ContactTile"; const Contact = () => { - return ( -
Contact
- ) -} + const social = (url) => () => { + window.open(url, "_blank", "noopener,noreferrer"); + }; + const [hoverAnimation, setHoverAnimation] = useState("animate__headShake"); -export default Contact \ No newline at end of file + const handleMouseEnter = (setAnimation) => { + setAnimation(hoverAnimation); // Trigger hover animation + }; + + const handleAnimationEnd = (setAnimation) => { + setAnimation(""); // Clear animation to prevent re-triggering + }; + return ( +
+ + + + + +
+ +
+
+ +
+ +
+ ); +}; + +export default Contact; diff --git a/src/components/subComponents/Contact/ContactTile.jsx b/src/components/subComponents/Contact/ContactTile.jsx new file mode 100644 index 0000000..92a1ac2 --- /dev/null +++ b/src/components/subComponents/Contact/ContactTile.jsx @@ -0,0 +1,98 @@ +import React, { useState } from "react"; +import "../../../css/ContactTile.css"; +import { useTheme } from "../../../Context/ThemeContext"; +import { useLang } from "../../../Context/LangContext"; + +const ContactTileTiltFlip = ({ + initialAnimation, + onMouseEnter, + onAnimationEnd, +}) => { + const [animation, setAnimation] = useState(initialAnimation); + const { colormode } = useTheme(); + const { language } = useLang(); + const [isFlipped, setIsFlipped] = useState(false); + const [tiltStyle, setTiltStyle] = useState({}); + + const handleMouseMove = (e) => { + const rect = e.currentTarget.getBoundingClientRect(); + const x = e.clientX - rect.left - rect.width / 2; + const y = e.clientY - rect.top - rect.height / 2; + const tiltX = (y / rect.height) * 40; // Harter Tilt + const tiltY = -(x / rect.width) * 40; + + setTiltStyle({ + transform: `rotateX(${tiltX}deg) rotateY(${tiltY}deg)`, + }); + }; + + const handleMouseLeave = () => { + setTiltStyle({ transform: "rotateX(0deg) rotateY(0deg)" }); + }; + + const handleClick = () => { + setIsFlipped(!isFlipped); + }; + + return ( +
onMouseEnter(setAnimation)} + */ onAnimationEnd={() => onAnimationEnd(setAnimation)} + > +
+
+
+

Yousif Paulus

+

React | Node.js | TypeScript

+

+ {language === "en-GB" + ? "Full-Stack Developer" + : "Full-Stack Entwickler"} +

+
+
+

+ 📧 {/* Email: */}{" "} + + yousif.paulus@hotmail.de + +

+

+ 📞{" "} + {/* {language === "en-GB" ? "Phone:" : "Tel:"} */} + + {language === "en-GB" + ? "+49 151 50717623" + : "0151 50717623"} + +

+ +

+ 🌐 {/* Portfolio: */}{" "} + www.yousifpaulus.dev +

+ {/*

+ 💬{" "} + {language === "en-GB" + ? "Let’s Build Something Great." + : "Tel: +49 151 50717623"} +

*/} +
+
+
+
+ ); +}; + +export default ContactTileTiltFlip; diff --git a/src/css/ContactTile.css b/src/css/ContactTile.css new file mode 100644 index 0000000..5b77262 --- /dev/null +++ b/src/css/ContactTile.css @@ -0,0 +1,163 @@ +.contactTile { + grid-area: 1 / 1 / 8 / 9; + display: flex; + justify-content: center; + align-items: center; +} + +.container.contactTile { + perspective: 1500px; /* Für 3D-Effekt */ +} + +.card { + width: 340px; /* Visitenkartenformat */ + height: 200px; + transform-style: preserve-3d; + cursor: pointer; + transition: transform 0.5s ease-out; /* Smooth Flip Transition */ +} + +.card.flipped { + transform: rotateY(180deg); /* Rückseite anzeigen */ +} + +.card-inner { + position: relative; + width: 100%; + height: 100%; + transform-style: preserve-3d; +} + +.card-front.dark h2 { + color: #333; +} + +.card-front, +.card-back { + position: absolute; + width: 100%; + height: 100%; + backface-visibility: hidden; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + border-radius: 10px; + background: linear-gradient(145deg, #d9d9d9, #f2f2f2); /* Helles Silber */ + box-shadow: inset 0 4px 8px rgba(255, 255, 255, 0.5), + inset 0 -4px 8px rgba(0, 0, 0, 0.1), 0 6px 10px rgba(0, 0, 0, 0.2); + overflow: hidden; /* Für Glanzeffekt-Beschneidung */ +} + +/* Rückseite - dunkler Silber-Look */ +.card-back { + background: linear-gradient(145deg, #999999, #b3b3b3); + transform: rotateY(180deg); + color: #333; +} + +.card-back p { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + padding: 0rem 3.5rem; +} + +.card-back p a { + color: #333; + font-weight: bold; + text-decoration: none; +} + +/* Glanzeffekt nur innerhalb der Karte */ +.card-front::before +/*, .card-back::before */ { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 150%; + height: 150%; + background: radial-gradient( + circle at 50% 50%, + rgba(255, 255, 255, 0.4), + rgba(255, 255, 255, 0) 70% + ); + transform: translate(-25%, -25%) rotate(30deg); + animation: subtle-glow 3s ease-in-out infinite; + pointer-events: none; + filter: blur(4px); + mix-blend-mode: screen; /* Lichtdurchlässigkeit */ +} + +/* Subtile Animation des Glanzes */ +@keyframes subtle-glow { + 0% { + transform: translate(-25%, -25%) rotate(30deg) scale(1.1); + } + 50% { + transform: translate(-25%, -25%) rotate(30deg) scale(1.3); + } + 100% { + transform: translate(-25%, -25%) rotate(30deg) scale(1.1); + } +} + +/* Light Mode Styles */ +.card-front.light, +.card-back.light { + background: linear-gradient( + 145deg, + #fdfdfd, + #e6e6e6 + ); /* Heller, weicher Silber-Look */ + box-shadow: inset 0 4px 8px rgba(255, 255, 255, 0.6), + inset 0 -4px 8px rgba(0, 0, 0, 0.1), 0 6px 10px rgba(0, 0, 0, 0.15); +} + +/* Vorderseite Light Mode */ +.card-front.light { + border: 1px solid #ddd; /* Leichte Kontur für hellen Look */ +} + +/* Rückseite Light Mode */ +.card-back.light { + border: 1px solid #ccc; /* Etwas dunklere Kontur für Kontrast */ + transform: rotateY(180deg); + color: #333; /* Dunkler Text für bessere Lesbarkeit */ +} + +/* Glanzeffekt für Light Mode */ +.card-front.light::before, +.card-back.light::before { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 150%; + height: 150%; + background: radial-gradient( + circle at 50% 50%, + rgba(255, 255, 255, 0.5), + rgba(255, 255, 255, 0) 70% + ); + transform: translate(-25%, -25%) rotate(30deg); + animation: subtle-glow-light 3s ease-in-out infinite; + pointer-events: none; + filter: blur(3px); + mix-blend-mode: overlay; /* Leicht transparenter Glanz */ +} + +/* Glanz-Animation für Light Mode */ +@keyframes subtle-glow-light { + 0% { + transform: translate(-25%, -25%) rotate(30deg) scale(1.05); + } + 50% { + transform: translate(-25%, -25%) rotate(30deg) scale(1.2); + } + 100% { + transform: translate(-25%, -25%) rotate(30deg) scale(1.05); + } +}