test
This commit is contained in:
26
app/Components/AboutMe.tsx
Normal file
26
app/Components/AboutMe.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
export default function AboutMe() {
|
||||
return (
|
||||
<div className="bg-gray-950 p-10 pb-32">
|
||||
<h1 className="title">About me</h1>
|
||||
<div className="flex">
|
||||
<div className="xl:w-1/3 max-xl:hidden"></div>
|
||||
<div className="xl:w-2/3 w-full items-center justify-center justify flex">
|
||||
<div>
|
||||
<h1 className="text-3xl">
|
||||
A{" "}
|
||||
<span className="drop-shadow-glow text-sky-300">
|
||||
Software Engineer
|
||||
</span>
|
||||
</h1>
|
||||
<p className="pb-5">With experience in</p>
|
||||
<li>DevOps</li>
|
||||
<li>FullStack Development</li>
|
||||
<li>Application Dvelopment</li>
|
||||
<li>Docker Containerization</li>
|
||||
<li>3D Designing</li>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
9
app/Components/Header.tsx
Normal file
9
app/Components/Header.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
export default function Header() {
|
||||
return (
|
||||
<div className="border-b border-gray-500 flex p-2">
|
||||
<a className="" href="/">
|
||||
HOME
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
138
app/Components/Projects.tsx
Normal file
138
app/Components/Projects.tsx
Normal file
@@ -0,0 +1,138 @@
|
||||
"use client";
|
||||
import React from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
export default function Projects() {
|
||||
const [Select, setSelect] = React.useState("empty");
|
||||
const router = useRouter();
|
||||
return (
|
||||
<motion.div
|
||||
className="m-10 p-3 border border-gray-700 rounded-md bg-gray-950"
|
||||
initial={{ x: 100, opacity: 0 }}
|
||||
whileInView={{ x: 0, opacity: 1 }}
|
||||
>
|
||||
<h1 className="title p-5">Projects</h1>
|
||||
<div className="flex">
|
||||
<div className="w-1/2 max-lg:w-full">
|
||||
<div
|
||||
onClick={() => router.push("/Projects/Portfolio")}
|
||||
className="m-4 p-3 border border-gray-700 rounded-md hover:bg-gray-800 cursor-pointer"
|
||||
onMouseOver={() => {
|
||||
setSelect("Portfolio");
|
||||
}}
|
||||
>
|
||||
<h1 className="float-right">June 2024</h1>
|
||||
<h1 className="card-title">Portfolio page</h1>
|
||||
<p className="card-body">
|
||||
A beige to show my experience and skills
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
onClick={() => router.push("/Projects/Buildify")}
|
||||
className="m-4 p-3 border border-gray-700 rounded-md hover:bg-gray-800 cursor-pointer"
|
||||
onMouseOver={() => setSelect("Buildify")}
|
||||
>
|
||||
<h1 className="float-right">May 2024</h1>
|
||||
<h1 className="card-title">Buildify</h1>
|
||||
<p className="card-body">
|
||||
My second graduation project for my bachelor's degree
|
||||
It's an application for creating CVs and making
|
||||
authentication links for your certificates
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
onClick={() => router.push("/Projects/Server")}
|
||||
className="m-4 p-3 border border-gray-700 rounded-md hover:bg-gray-800 cursor-pointer"
|
||||
onMouseOver={() => setSelect("Server")}
|
||||
>
|
||||
<h1 className="float-right">December 2022</h1>
|
||||
<h1 className="card-title">Home Server</h1>
|
||||
<p className="card-body">
|
||||
A file server with ZFS redundant storage, hosting more than 30
|
||||
Docker
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
onClick={() => router.push("/Projects/Library")}
|
||||
className="m-4 p-3 border border-gray-700 rounded-md hover:bg-gray-800 cursor-pointer"
|
||||
onMouseOver={() => setSelect("Library")}
|
||||
>
|
||||
<h1 className="float-right">January 2022</h1>
|
||||
<h1 className="card-title">Library store website</h1>
|
||||
<p className="card-body">
|
||||
A graduation project for my associate's degree.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<motion.div
|
||||
className="w-1/2 m-4 p-3 border border-gray-700 rounded-md max-lg:hidden"
|
||||
hidden={Select !== "empty"}
|
||||
></motion.div>
|
||||
<motion.div
|
||||
className="w-1/2 m-4 p-3 border border-gray-700 rounded-md max-lg:hidden relative"
|
||||
hidden={Select !== "Portfolio"}
|
||||
>
|
||||
<h1 className="text-xl p-3">Portfolio page</h1>
|
||||
<p>
|
||||
A showcase of my expertise in programming and design, highlighting
|
||||
my achievements in creating intuitive digital experiences.
|
||||
</p>
|
||||
<ul className="list-disc list-inside">
|
||||
<p>Crafted using :</p>
|
||||
<li>React</li>
|
||||
<li>Next.js</li>
|
||||
<li>Tailwind CSS</li>
|
||||
<li>TypeScript</li>
|
||||
<li>Framer Motion</li>
|
||||
<li>MongoDB</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
<motion.div
|
||||
className="w-1/2 m-4 p-3 border border-gray-700 rounded-md max-lg:hidden"
|
||||
hidden={Select !== "Buildify"}
|
||||
>
|
||||
<h1 className="text-xl p-3">Buildify</h1>
|
||||
<p>
|
||||
My second graduation project for my bachelor's degree It's
|
||||
an application for creating CVs and making authentication links for
|
||||
your certificates.
|
||||
</p>
|
||||
<ul className="list-disc list-inside">
|
||||
<li>React</li>
|
||||
<li>Next.js</li>
|
||||
<li>Flutter</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
<motion.div
|
||||
className="w-1/2 m-4 p-3 border border-gray-700 rounded-md max-lg:hidden"
|
||||
hidden={Select !== "Server"}
|
||||
>
|
||||
<h1 className="text-xl p-3">Home Server</h1>
|
||||
<p>
|
||||
A file server with ZFS redundant storage, hosting more than 30
|
||||
Docker containers including:
|
||||
</p>
|
||||
<ul className="list-disc list-inside">
|
||||
<li>Smart home server</li>
|
||||
<li>DNS server</li>
|
||||
<li>Git server</li>
|
||||
<li>VPN server</li>
|
||||
<li>NextCloud</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
<motion.div
|
||||
className="w-1/2 m-4 p-3 border border-gray-700 rounded-md max-lg:hidden"
|
||||
hidden={Select !== "Library"}
|
||||
>
|
||||
<h1 className="text-xl p-3">Library store website</h1>
|
||||
<p>
|
||||
A graduation project for my associate's degree. We used HTML,
|
||||
CSS, and JavaScript for the front-end, and PHP and SQL for the
|
||||
back-end.
|
||||
</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
104
app/Components/SendMessage.tsx
Normal file
104
app/Components/SendMessage.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
"use client";
|
||||
import axios from "axios";
|
||||
import React from "react";
|
||||
import { motion } from "framer-motion";
|
||||
export default function SendMessage() {
|
||||
const [infomis, setinfomis] = React.useState("");
|
||||
async function handleSubmit(e: any) {
|
||||
e.preventDefault();
|
||||
const name = e.target.name.value;
|
||||
const email = e.target.email.value;
|
||||
const subject = e.target.subject.value;
|
||||
const body = e.target.body.value;
|
||||
let error = false;
|
||||
if (name === "") {
|
||||
e.currentTarget.name.className = "inputEroor";
|
||||
error = true;
|
||||
}
|
||||
if (email === "") {
|
||||
e.currentTarget.email.className = "inputEroor";
|
||||
error = true;
|
||||
}
|
||||
if (subject === "") {
|
||||
e.currentTarget.subject.className = "inputEroor";
|
||||
error = true;
|
||||
}
|
||||
if (body === "") {
|
||||
e.currentTarget.body.className = "inputEroor w-full";
|
||||
error = true;
|
||||
}
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
console.log(name, email, subject, body);
|
||||
await axios
|
||||
.post("/api/message", { name, email, subject, body })
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.success) {
|
||||
e.target.name.value = "";
|
||||
e.target.email.value = "";
|
||||
e.target.subject.value = "";
|
||||
e.target.body.value = "";
|
||||
setinfomis("Message sent successfully");
|
||||
}
|
||||
});
|
||||
}
|
||||
return (
|
||||
<motion.form
|
||||
initial={{ x: 100, opacity: 0 }}
|
||||
whileInView={{ x: 0, opacity: 1 }}
|
||||
onSubmit={handleSubmit}
|
||||
className="m-10 p-3 border border-gray-700 rounded-md bg-gray-950"
|
||||
>
|
||||
<h1 className="text-3xl pl-10 p-5">Send a message</h1>
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
id="name"
|
||||
placeholder="Name"
|
||||
className="input"
|
||||
onClick={(e) => {
|
||||
e.currentTarget.className = "input";
|
||||
}}
|
||||
/>
|
||||
<input
|
||||
name="email"
|
||||
id="email"
|
||||
placeholder="Email"
|
||||
className="input"
|
||||
onClick={(e) => {
|
||||
e.currentTarget.className = "input";
|
||||
}}
|
||||
/>
|
||||
<input
|
||||
type="subject"
|
||||
name="subject"
|
||||
id="subject"
|
||||
placeholder="Subject"
|
||||
className="input"
|
||||
onClick={(e) => {
|
||||
e.currentTarget.className = "input";
|
||||
}}
|
||||
/>
|
||||
|
||||
<textarea
|
||||
name="body"
|
||||
id="body"
|
||||
cols={10}
|
||||
rows={3}
|
||||
placeholder="Message"
|
||||
className="input w-11/12"
|
||||
onClick={(e) => {
|
||||
e.currentTarget.className = "input w-full";
|
||||
}}
|
||||
/>
|
||||
<h2 className="text-green-600">{infomis}</h2>
|
||||
<button className="ml-5 m-5 inline-block text-white font-bold py-2 px-4 rounded-full bg-gradient-to-r from-sky-500 to-blue-700 border border-transparent transform hover:scale-110 hover:border-white transition-transform duration-3000 ease-in-out w-28 text-center">
|
||||
Send
|
||||
</button>
|
||||
</motion.form>
|
||||
);
|
||||
}
|
||||
12
app/Components/footer.tsx
Normal file
12
app/Components/footer.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
export default function Footer() {
|
||||
return (
|
||||
<div className="p-10 bg-gray-950 text-xl text-white">
|
||||
<div className="border-l-2 pl-9 border-white">
|
||||
<p>saad@s3d340.com</p>
|
||||
<p>s3d340@gmail.com</p>
|
||||
<p>+966 535235140</p>
|
||||
</div>
|
||||
<p className="pt-5">© 2024 - Saad Alkathiri.</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user