Skip to content

Commit

Permalink
feat: optimize Contact component with form submission functionality a…
Browse files Browse the repository at this point in the history
…nd animations
  • Loading branch information
mces58 committed Aug 9, 2024
1 parent 1eed860 commit 40bbe26
Show file tree
Hide file tree
Showing 2 changed files with 171 additions and 3 deletions.
131 changes: 128 additions & 3 deletions v2/src/components/Contact.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,132 @@
import React from 'react';
import { useRef, useState } from 'react';

import emailjs from '@emailjs/browser';
import { motion } from 'framer-motion';

import EarthCanvas from '@/components/canvas/Earth';
import SectionWrapper from '@/hoc/SectionWrapper';
import { styles } from '@/styles';
import { slideIn } from '@/utils/motion';

const Contact = () => {
return <div>Contact</div>;
const formRef = useRef();
const [form, setForm] = useState({
name: '',
email: '',
message: '',
});

const [loading, setLoading] = useState(false);

const handleChange = (e) => {
const { target } = e;
const { name, value } = target;

setForm({
...form,
[name]: value,
});
};

const handleSubmit = (e) => {
e.preventDefault();
setLoading(true);

emailjs
.send(
import.meta.env.VITE_APP_EMAILJS_SERVICE_ID,
import.meta.env.VITE_APP_EMAILJS_TEMPLATE_ID,
{
from_name: form.name,
to_name: 'JavaScript Mastery',
from_email: form.email,
to_email: 'sujata@jsmastery.pro',
message: form.message,
},
import.meta.env.VITE_APP_EMAILJS_PUBLIC_KEY
)
.then(
() => {
setLoading(false);
alert('Thank you. I will get back to you as soon as possible.');

setForm({
name: '',
email: '',
message: '',
});
},
(error) => {
setLoading(false);
console.error(error);

alert('Ahh, something went wrong. Please try again.');
}
);
};
return (
<div className={`xl:mt-12 flex xl:flex-row flex-col-reverse gap-10 overflow-hidden`}>
<motion.div
variants={slideIn('left', 'tween', 0.2, 1)}
className="flex-[0.75] bg-black-100 p-8 rounded-2xl"
>
<p className={styles.sectionSubText}>Get in touch</p>
<h3 className={styles.sectionHeadText}>Contact.</h3>

<form ref={formRef} onSubmit={handleSubmit} className="mt-12 flex flex-col gap-8">
<label className="flex flex-col">
<span className="text-white font-medium mb-4">Your Name</span>
<input
type="text"
name="name"
value={form.name}
onChange={handleChange}
placeholder="What's your good name?"
className="bg-tertiary py-4 px-6 placeholder:text-secondary text-white rounded-lg outline-none border-none font-medium"
/>
</label>
<label className="flex flex-col">
<span className="text-white font-medium mb-4">Your email</span>
<input
type="email"
name="email"
value={form.email}
onChange={handleChange}
placeholder="What's your web address?"
className="bg-tertiary py-4 px-6 placeholder:text-secondary text-white rounded-lg outline-none border-none font-medium"
/>
</label>
<label className="flex flex-col">
<span className="text-white font-medium mb-4">Your Message</span>
<textarea
rows={7}
name="message"
value={form.message}
onChange={handleChange}
placeholder="What you want to say?"
className="bg-tertiary py-4 px-6 placeholder:text-secondary text-white rounded-lg outline-none border-none font-medium"
/>
</label>

<button
type="submit"
className="bg-tertiary py-3 px-8 rounded-xl outline-none w-fit text-white font-bold shadow-md shadow-primary"
>
{loading ? 'Sending...' : 'Send'}
</button>
</form>
</motion.div>

<motion.div
variants={slideIn('right', 'tween', 0.2, 1)}
className="xl:flex-1 xl:h-auto md:h-[550px] h-[350px]"
>
<EarthCanvas />
</motion.div>
</div>
);
};

export default Contact;
const WrappedContact = SectionWrapper(Contact, 'contact');

export default WrappedContact;
43 changes: 43 additions & 0 deletions v2/src/components/canvas/Earth.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Suspense } from 'react';

import { OrbitControls, Preload, useGLTF } from '@react-three/drei';
import { Canvas } from '@react-three/fiber';

import CanvasLoader from '@/components/Loader';

const Earth = () => {
const earth = useGLTF('./planet/scene.gltf');

return <primitive object={earth.scene} scale={2.5} position-y={0} rotation-y={0} />;
};

const EarthCanvas = () => {
return (
<Canvas
shadows
frameloop="demand"
dpr={[1, 2]}
gl={{ preserveDrawingBuffer: true }}
camera={{
fov: 45,
near: 0.1,
far: 200,
position: [-4, 3, 6],
}}
>
<Suspense fallback={<CanvasLoader />}>
<OrbitControls
autoRotate
enableZoom={false}
maxPolarAngle={Math.PI / 2}
minPolarAngle={Math.PI / 2}
/>
<Earth />

<Preload all />
</Suspense>
</Canvas>
);
};

export default EarthCanvas;

0 comments on commit 40bbe26

Please sign in to comment.