This commit is contained in:
Saad AlKathiri 2025-03-27 18:26:47 +03:00
parent 12fc59c524
commit 5d25258f20
59 changed files with 6281 additions and 0 deletions

3
.eslintrc.json Normal file
View File

@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}

36
.gitignore vendored Normal file
View File

@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts

0
Build Normal file
View File

View 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>
);
}

View 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
View 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&apos;s degree
It&apos;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&apos;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&apos;s degree It&apos;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&apos;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>
);
}

View 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
View 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>
);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -0,0 +1,122 @@
import Header from "@/app/Components/Header";
import Image from "next/image";
import Picture1 from "./img/Picture1.png";
import Picture2 from "./img/Picture2.png";
import Picture3 from "./img/Picture3.png";
import Picture4 from "./img/Picture4.png";
import Picture5 from "./img/Picture5.png";
import Picture6 from "./img/Picture6.png";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Buildify",
description: "CV/Resume Sharing and Authentication Application",
};
export default function Buildify() {
return (
<>
<Header />
<div className="m-10 border border-gray-700 rounded-md bg-gray-950 lg:flex max-sm:m-5">
<div className="lg:w-2/3 border-r border-gray-700">
<div className="projects-grid">
<h1 className="text-5xl">Buildify</h1>
<p className="pb-5 card-body">
CV/Resume Sharing and Authentication Application
</p>
<p className="text-lg ">
This project is a CV/Resume Sharing and Authentication Application
designed to help individuals manage and share their resumes/CVs
while ensuring the authenticity of the information. The
application provides a platform for users to update their career
progress and for organizations to verify the credentials of
potential employees.
</p>
</div>
<div className="projects-grid">
<h1 className="title p-2">Goal of the Project</h1>
<p>
The primary goal of the project is to develop an application that
simplifies the process of creating, sharing, and authenticating
CVs/resumes. This ensures that organizations can trust the
information presented by job applicants, thereby improving the
hiring process and reducing fraudulent claims.
</p>
</div>
<div className="projects-grid">
<h1 className="title p-2">Key Features</h1>
<ul className="list-disc list-inside">
<li>
Creating CVs/Resumes: Users can create and update their
CVs/resumes.
</li>
<li>
Certificate Authentication: Users can upload and get their
certificates authenticated to add credibility to their resumes.
</li>
<li>
Secure User and Admin Login: The application employs JWT (JSON
Web Token) for generating secure tokens, ensuring that only
authenticated users and admins can access the system.
</li>
<li>
Search Functionality: Organizations and other users can search
for and view authenticated resumes.
</li>
<li>
Admin Portal: Administrators have a dedicated web application to
manage users, resumes, and authentication processes.
</li>
</ul>
</div>
<div className="projects-grid">
<h1 className="title p-2">Program Languages and Tools Used</h1>
<ul className="list-disc list-inside">
<li>React.js</li>
<li>TypeScript</li>
<li>Flutter</li>
<li>Dart</li>
<li>OpenAI</li>
<li>Visual Studio Code.</li>
<li>Android Studio.</li>
</ul>
</div>
<div className="projects-grid">
<h1 className="title p-2">Team</h1>
<ul className="list-disc list-inside">
<li>Saad Alkathiri</li>
<li>Marouf Alsubaie</li>
</ul>
</div>
<div className="projects-grid">
<h1 className="title p-2">Conclusion</h1>
<p>
The CV/Resume Sharing and Authentication Application enhances the
trustworthiness of resumes by ensuring that all information is
verified and authenticated. This project aims to facilitate a more
reliable hiring process for organizations and provide individuals
with a credible platform to showcase their career achievements.
Future work will focus on better integration with organizations
for seamless authentication and design enhancements for an
improved user experience.
</p>
</div>
<div className="p-12">
<h1 className="title p-2">full documentation</h1>
<p>You can find the full documentation here</p>
<a className="text-blue-600" href="https://s3d340.com/Buildify">
https://s3d340.com/Buildify
</a>
</div>
</div>
<div className="lg:w-1/3 grid grid-cols-2 gap-4">
<Image src={Picture1} alt="Picture1" className="p-3" />
<Image src={Picture2} alt="Picture2" className="p-3" />
<Image src={Picture3} alt="Picture3" className="p-3" />
<Image src={Picture4} alt="Picture4" className="p-3" />
<Image src={Picture5} alt="Picture5" className="p-3" />
<Image src={Picture6} alt="Picture6" className="p-3" />
</div>
</div>
</>
);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 851 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 558 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@ -0,0 +1,136 @@
import Header from "@/app/Components/Header";
import Image from "next/image";
import Picture1 from "./img/Picture1.png";
import Picture4 from "./img/Picture4.png";
import Picture6 from "./img/Picture6.png";
import Picture8 from "./img/Picture8.png";
import Picture9 from "./img/Picture9.png";
import Picture10 from "./img/Picture10.png";
import Picture13 from "./img/Picture13.png";
import Picture16 from "./img/Picture16.png";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Library",
description: "E-COMMERCE Platform for Educational and Recreational Books",
};
export default function Library() {
return (
<>
<Header />
<div className="m-10 border border-gray-700 rounded-md bg-gray-950 lg:flex max-sm:m-5">
<div className="lg:w-2/3 border-r border-gray-700">
<div className="projects-grid">
<h1 className="text-4xl pb-5 max-sm:title">
E-COMMERCE Platform for Educational and Recreational Books
</h1>
<p className=" text-lg">
My second graduation project for my bachelor&apos;s degree
It&apos;s an application for creating CVs and making
authentication links for your certificates.
</p>
</div>
<div className="projects-grid">
<h1 className="title p-2">Introduction</h1>
<p>
This project represents the beginning of my career in programming
and is my graduation project for my associate degree. It showcases
my skills and knowledge in developing a comprehensive e-commerce
platform dedicated to selling various types of books, including
educational, self-help, and novels.
</p>
</div>
<div className="projects-grid">
<h1 className="title p-2">Project Idea</h1>
<p>
The project&apos;s primary goal is to create a user-friendly
website that facilitates the purchase of educational and
recreational books. The platform aims to encourage reading and
provide a seamless shopping experience for students and book
enthusiasts.
</p>
</div>
<div className="projects-grid">
<h1 className="title p-2">Objectives</h1>
<ul className="list-disc list-inside">
<li>
Simplify the process of buying books and supplies for customers
</li>
<li>Ensure ease of use for the website </li>
</ul>
</div>
<div className="projects-grid">
<h1 className="title p-2">Tools and Technologies</h1>
<ul className="list-disc list-inside">
<li>WampServer: For creating a local server environment.</li>
<li>phpMyAdmin: For database management. </li>
<li>
Visual Studio Code: For code editing and development using PHP,
HTML, CSS, and JavaScript.
</li>
<li>
GitHub: For version control and collaboration among team
members.
</li>
<li>
Visual Paradigm: For designing diagrams like use case,
flowchart, and ERD.
</li>
</ul>
</div>
<div className="projects-grid">
<h1 className="title p-2">Programming Languages</h1>
<ul className="list-disc list-inside">
<li>PHP.</li>
<li>HTML and CSS. </li>
<li>SQL</li>
<li>JavaScript</li>
</ul>
</div>
<div className="projects-grid">
<h1 className="title p-2">Development Model</h1>
<p>
Incremental Development: Chosen because it allows for easy
modifications and improvements in the project specifications over
time.
</p>
</div>
<div className="projects-grid">
<h1 className="title p-2">Team</h1>
<ul className="list-disc list-inside">
<li>Saad Alkathiri</li>
<li>Marouf AlSubaie </li>
<li>Fares AlQahtani </li>
</ul>
</div>
<div className="projects-grid">
<h1 className="title p-2">Conclusion</h1>
<p>
This project has been a valuable learning experience, helping us
improve our skills and work as a cohesive team. We hope our
efforts result in a useful and appreciated platform for book
lovers and students.
</p>
</div>
<div className="p-12">
<h1 className="title p-2">full documentation</h1>
<p>You can find the full documentation here</p>
<a className="text-blue-600" href="https://s3d340.com/E-COMMERCE">
https://s3d340.com/E-COMMERCE
</a>
</div>
</div>
<div className="lg:w-1/3">
<Image src={Picture1} alt="Picture1" className="p-3" />
<Image src={Picture4} alt="Picture4" className="p-3" />
<Image src={Picture6} alt="Picture6" className="p-3" />
<Image src={Picture8} alt="Picture8" className="p-3" />
<Image src={Picture9} alt="Picture9" className="p-3" />
<Image src={Picture10} alt="Picture10" className="p-3" />
<Image src={Picture13} alt="Picture13" className="p-3" />
<Image src={Picture16} alt="Picture16" className="p-3" />
</div>
</div>
</>
);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -0,0 +1,110 @@
import Header from "@/app/Components/Header";
import Image from "next/image";
import Picture1 from "./img/Screenshot 2024-06-21 004106.png";
import Picture2 from "./img/Screenshot 2024-06-21 004132.png";
import Picture3 from "./img/Screenshot 2024-06-21 004200.png";
import Picture4 from "./img/Screenshot 2024-06-21 004223.png";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Portfolio",
description: "My Portfolio Website",
};
export default function Portfolio() {
return (
<>
<Header />
<div className="m-10 border border-gray-700 rounded-md bg-gray-950 lg:flex max-sm:m-5">
<div className="lg:w-2/3 border-r border-gray-700">
<div className="projects-grid">
<h1 className="text-5xl">Portfolio Website</h1>
<p className="pb-5 card-body">
This project Is being used and updated
</p>
<p className="text-lg">
This portfolio website is a showcase of my expertise in
programming and design, highlighting my achievements in creating
intuitive and engaging digital experiences.
</p>
</div>
<div className="projects-grid">
<h1 className="title p-2">Goal of the Project</h1>
<p>
The primary goal of this project is to present my skills,
projects, and professional achievements in a visually appealing
and easily navigable format. It aims to attract potential
employers or clients by demonstrating my proficiency in modern web
development and design technologies.
</p>
</div>
<div className="projects-grid">
<h1 className="title p-2">Key Features</h1>
<ul className="list-disc list-inside">
<li>
Professional Showcase: Displays a curated selection of my
projects, skills, and professional milestones.
</li>
<li>
Responsive Design: Ensures optimal viewing experience across a
wide range of devices, from desktops to mobile phones.
</li>
<li>
Interactive Elements: Incorporates engaging animations and
interactive components to enhance user experience.
</li>
<li>
Contact Form: Provides an easy way for potential clients or
employers to get in touch.
</li>
</ul>
</div>
<div className="projects-grid">
<h1 className="title p-2">Program Languages and Tools Used</h1>
<ul className="list-disc list-inside">
<li>React: For building the user interface.</li>
<li>
Next.js: For server-side rendering and enhanced performance.
</li>
<li>Tailwind CSS: For streamlined and responsive styling.</li>
<li>
TypeScript: For type safety and enhanced code maintainability.
</li>
<li>
Framer Motion: For creating smooth animations and transitions.
</li>
<li>MongoDB: For managing and storing content data.</li>
</ul>
</div>
<div className="projects-grid">
<h1 className="title p-2">Conclusion</h1>
<p>
This portfolio website effectively demonstrates my capabilities in
web development and design, offering a comprehensive view of my
professional skills and accomplishments. By leveraging modern
technologies, it provides an engaging and seamless user experience
that reflects my commitment to creating high-quality digital
solutions.
</p>
</div>
<div className="p-12">
<h1 className="title p-2">full documentation</h1>
<p>You can find the full Project files in Github</p>
<a
className="text-blue-600"
href="https://github.com/DevilCode0/MyPortfolioPage"
>
https://github.com/DevilCode0/MyPortfolioPage
</a>
</div>
</div>
<div className="lg:w-1/3">
<Image src={Picture1} alt="Picture1" />
<Image src={Picture2} alt="Picture2" />
<Image src={Picture3} alt="Picture3" />
<Image src={Picture4} alt="Picture4" />
</div>
</div>
</>
);
}

View File

@ -0,0 +1,89 @@
import Header from "@/app/Components/Header";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Home Server",
description: "My Home Server",
};
export default function page() {
return (
<>
<Header />
<div className="m-10 border border-gray-700 rounded-md bg-gray-950 max-sm:m-5">
<div className=" border-gray-700">
<div className="projects-grid">
<h1 className="text-5xl">Home Server</h1>
<p className="pb-5 card-body">
This project Is being used and updated
</p>
<p className="text-lg">
This project is a home server equipped with ZFS redundant storage,
hosting over 30 Docker containers that support various services
including smart home automation, DNS, Git, VPN, and NextCloud.
</p>
</div>
<div className="projects-grid">
<h1 className="title p-2">Goal of the Project</h1>
<p>
The primary goal of this project is to create a reliable and
secure home server that centralizes and manages multiple services
efficiently. By using Docker containers and ZFS storage, the
project aims to ensure data redundancy, ease of management, and
high availability for essential home and development services.
</p>
</div>
<div className="projects-grid">
<h1 className="title p-2">Key Features</h1>
<ul className="list-disc list-inside">
<li>
ZFS Redundant Storage: Ensures data integrity and protection
through advanced features like snapshots, replication, and
self-healing.
</li>
<li>
Smart Home Server: Manages and automates various smart home
devices for improved convenience and energy efficiency.
</li>
<li>
DNS Server: Provides a local DNS service for faster and more
reliable network name resolution.
</li>
<li>
Git Server: Hosts Git repositories for version control and
collaborative development.
</li>
<li>
VPN Server: Offers secure remote access to the home network,
ensuring privacy and protection.
</li>
<li>
NextCloud: Provides a personal cloud solution for file storage,
synchronization, and sharing.
</li>
</ul>
</div>
<div className="projects-grid">
<h1 className="title p-2">Conclusion</h1>
<p>
The home server project demonstrates the effective use of Docker
and ZFS to create a versatile and robust home network
infrastructure. By integrating multiple services, it offers
enhanced data security, improved home automation, and streamlined
management of development and personal resources.
</p>
</div>
<div className="p-12">
<h1 className="title p-2">full documentation</h1>
<p>
Due to the private nature of this home server project, detailed
documentation is not available for public distribution. This
ensures the security and privacy of the personal and sensitive
information managed by the server.
</p>
</div>
</div>
</div>
</>
);
}

BIN
app/Thumbs.db Normal file

Binary file not shown.

29
app/api/message/route.ts Normal file
View File

@ -0,0 +1,29 @@
import {conict} from "@/dbconfig/config";
import message from "@/dbconfig/models/message";
import { NextRequest,NextResponse } from "next/server";
conict()
export async function POST(request: NextRequest) {
console.log("run");
try {
const { name,email,subject,body } = await request.json();
const newMessage = new message({
name,
email,
subject,
body,
});
const savedMessage = await newMessage.save();
console.log(savedMessage);
return NextResponse.json({
message: "User created successfully",
success: true,
});
} catch (error: any) {
return NextResponse.json({ error: error.message }, { status: 500 });
}
}

BIN
app/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

24
app/globals.css Normal file
View File

@ -0,0 +1,24 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.input {
@apply bg-slate-800 rounded-sm m-3
}
.inputEroor {
@apply border border-red-500 bg-slate-800 rounded-sm m-3
}
.card-title{
@apply text-left text-lg pb-2
}
.card-body{
@apply text-gray-400
}
.title{
@apply text-3xl pb-20
}
.projects-grid{
@apply p-12 border-b border-gray-700 max-sm:p-5
}
}

32
app/layout.tsx Normal file
View File

@ -0,0 +1,32 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import Footer from "./Components/footer";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: {
default: "Saad Alkathiri",
template: "%s | Saad Alkathiri",
},
description: "Portfolio page for Saad",
twitter: {
card: "summary_large_image",
},
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={(inter.className, "bg-gray-900 text-white")}>
{children}
<Footer />
</body>
</html>
);
}

BIN
app/opengraph-image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

59
app/page.tsx Normal file
View File

@ -0,0 +1,59 @@
import Image from "next/image";
import SendMessage from "./Components/SendMessage";
import Projects from "./Components/Projects";
import AboutMe from "./Components/AboutMe";
export default function Home() {
return (
<>
<div className="h-screen flex items-center">
<div className="xl:w-1/2 max-md:w-full justify-center flex">
<div className="text-white p-12 w-5/6">
<h1 className="text-5xl xl:text-7xl drop-shadow-glow ">
Saad Alkathiri
</h1>
<p className="p-2">
Software engineer with a strong foundation in computer programming
and experience in web development, devops, and docker
containerization. Seeking an opportunity to contribute my
technical expertise and passion for software production. Committed
to delivering high-quality solutions and continuously expanding my
knowledge in the ever-evolving field of software engineering.
</p>
<div className="flex pt-11">
<a href="https://www.linkedin.com/in/saad-alkathiri/">
<svg
className="fill-slate-50 hover:fill-slate-400 hover:scale-110 transition-transform duration-3000 ease-in-out"
width="40px"
height="40px"
viewBox="0 0 16 16"
>
<path d="M12.225 12.225h-1.778V9.44c0-.664-.012-1.519-.925-1.519-.926 0-1.068.724-1.068 1.47v2.834H6.676V6.498h1.707v.783h.024c.348-.594.996-.95 1.684-.925 1.802 0 2.135 1.185 2.135 2.728l-.001 3.14zM4.67 5.715a1.037 1.037 0 01-1.032-1.031c0-.566.466-1.032 1.032-1.032.566 0 1.031.466 1.032 1.032 0 .566-.466 1.032-1.032 1.032zm.889 6.51h-1.78V6.498h1.78v5.727zM13.11 2H2.885A.88.88 0 002 2.866v10.268a.88.88 0 00.885.866h10.226a.882.882 0 00.889-.866V2.865a.88.88 0 00-.889-.864z" />
</svg>
</a>
<a href="https://github.com/DevilCode0/">
<svg
className="fill-slate-50 hover:fill-slate-400 hover:scale-110 transition-transform duration-3000 ease-in-out"
width="40px"
height="40px"
viewBox="0 0 16 16"
>
<path d="M8 1C4.133 1 1 4.13 1 7.993c0 3.09 2.006 5.71 4.787 6.635.35.064.478-.152.478-.337 0-.166-.006-.606-.01-1.19-1.947.423-2.357-.937-2.357-.937-.319-.808-.778-1.023-.778-1.023-.635-.434.048-.425.048-.425.703.05 1.073.72 1.073.72.624 1.07 1.638.76 2.037.582.063-.452.244-.76.444-.935-1.554-.176-3.188-.776-3.188-3.456 0-.763.273-1.388.72-1.876-.072-.177-.312-.888.07-1.85 0 0 .586-.189 1.924.716A6.711 6.711 0 018 4.381c.595.003 1.194.08 1.753.236 1.336-.905 1.923-.717 1.923-.717.382.963.142 1.674.07 1.85.448.49.72 1.114.72 1.877 0 2.686-1.638 3.278-3.197 3.45.251.216.475.643.475 1.296 0 .934-.009 1.688-.009 1.918 0 .187.127.404.482.336A6.996 6.996 0 0015 7.993 6.997 6.997 0 008 1z" />{" "}
</svg>
</a>
</div>
<a
href="https://next.s3d340.com/s/LppJa2K7ZgdGwtZ"
className="mt-4 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"
>
Download my CV
</a>
</div>
</div>
<div className="xl:w-1/2 md:w-full justify-center flex phone:max-md:hidden"></div>
</div>
<AboutMe />
<Projects />
<SendMessage />
</>
);
}

12
app/robots.ts Normal file
View File

@ -0,0 +1,12 @@
import { MetadataRoute } from 'next'
export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: "*",
allow: "/",
disallow: "/private/",
},
sitemap: `${process.env.SITE_URL}/sitemap.xml`,
};
}

30
app/sitemap.ts Normal file
View File

@ -0,0 +1,30 @@
import { MetadataRoute } from 'next'
export default function sitemap(): MetadataRoute.Sitemap {
return [
{
url: `${process.env.SITE_URL}`,
priority: 1,
},
{
url: `${process.env.SITE_URL}/Projects/Portfolio`,
priority: 0.1,
},
{
url: `${process.env.SITE_URL}/Projects/Buildify`,
priority: 0.1,
},
{
url: `${process.env.SITE_URL}/Projects/Server`,
priority: 0.1,
},
{
url: `${process.env.SITE_URL}/Projects/Library`,
priority: 0.1,
},
{
url: `${process.env.SITE_URL}`,
priority: 0.1,
},
];
}

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="none"><path fill="#000000" fill-rule="evenodd" d="M8 1C4.133 1 1 4.13 1 7.993c0 3.09 2.006 5.71 4.787 6.635.35.064.478-.152.478-.337 0-.166-.006-.606-.01-1.19-1.947.423-2.357-.937-2.357-.937-.319-.808-.778-1.023-.778-1.023-.635-.434.048-.425.048-.425.703.05 1.073.72 1.073.72.624 1.07 1.638.76 2.037.582.063-.452.244-.76.444-.935-1.554-.176-3.188-.776-3.188-3.456 0-.763.273-1.388.72-1.876-.072-.177-.312-.888.07-1.85 0 0 .586-.189 1.924.716A6.711 6.711 0 018 4.381c.595.003 1.194.08 1.753.236 1.336-.905 1.923-.717 1.923-.717.382.963.142 1.674.07 1.85.448.49.72 1.114.72 1.877 0 2.686-1.638 3.278-3.197 3.45.251.216.475.643.475 1.296 0 .934-.009 1.688-.009 1.918 0 .187.127.404.482.336A6.996 6.996 0 0015 7.993 6.997 6.997 0 008 1z" clip-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 975 B

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="none"><path fill="#000000" d="M12.225 12.225h-1.778V9.44c0-.664-.012-1.519-.925-1.519-.926 0-1.068.724-1.068 1.47v2.834H6.676V6.498h1.707v.783h.024c.348-.594.996-.95 1.684-.925 1.802 0 2.135 1.185 2.135 2.728l-.001 3.14zM4.67 5.715a1.037 1.037 0 01-1.032-1.031c0-.566.466-1.032 1.032-1.032.566 0 1.031.466 1.032 1.032 0 .566-.466 1.032-1.032 1.032zm.889 6.51h-1.78V6.498h1.78v5.727zM13.11 2H2.885A.88.88 0 002 2.866v10.268a.88.88 0 00.885.866h10.226a.882.882 0 00.889-.866V2.865a.88.88 0 00-.889-.864z"/></svg>

After

Width:  |  Height:  |  Size: 724 B

18
dbconfig/config.ts Normal file
View File

@ -0,0 +1,18 @@
import mangoose from'mongoose';
export async function conict() {
try {
await mangoose.connect(process.env.MONGO_URI!)
const connection = mangoose.connection;
connection.on('connect', () => {
console.log('conicted to MongoDB');
});
connection.on('error', (error) => {
console.log('Error connecting to MongoDB', error);
process.exit();
});
} catch (error) {
console.log('Erro ao conectar', error);
}
}

View File

@ -0,0 +1,14 @@
import mongoose from 'mongoose';
const messageSchema = new mongoose.Schema({
name: {type: String, required: [true, 'Name is required']},
email: {type: String, required: [true, 'Email is required']},
subject: {type: String, required: [true, 'Subject is required']},
body : {type: String, required: [true, 'Message is required']},
createdAt: {type: Date, default: Date.now},
});
const message = mongoose.models.messages || mongoose.model('messages', messageSchema);
export default message;

17
dockerfile Normal file
View File

@ -0,0 +1,17 @@
FROM node:18-alpine
WORKDIR /usr/src/app
# Copy package.json and package-lock.json first (for better caching)
COPY package*.json ./
# Install all dependencies (both production & dev)
RUN npm install
# Copy the rest of the application
COPY . .
# Build the application
RUN npm run build
CMD [ "npm", "run", "start" ]

4
next.config.mjs Normal file
View File

@ -0,0 +1,4 @@
/** @type {import('next').NextConfig} */
const nextConfig = {};
export default nextConfig;

5153
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

30
package.json Normal file
View File

@ -0,0 +1,30 @@
{
"name": "portfolio",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"axios": "^1.7.2",
"framer-motion": "^11.2.10",
"mongodb": "^6.7.0",
"mongoose": "^8.4.1",
"next": "14.2.3",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"eslint": "^8",
"eslint-config-next": "14.2.3",
"postcss": "^8",
"tailwindcss": "^3.4.1",
"typescript": "^5"
}
}

8
postcss.config.mjs Normal file
View File

@ -0,0 +1,8 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
tailwindcss: {},
},
};
export default config;

1
public/next.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

1
public/vercel.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg>

After

Width:  |  Height:  |  Size: 629 B

34
tailwind.config.ts Normal file
View File

@ -0,0 +1,34 @@
import type { Config } from "tailwindcss";
const config: Config = {
content: [
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"./app/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
extend: {
screens: {
'phone': '0px',
'laptop': '1024px',
'desktop': '1280px',
// => @media (min-width: 1280px) { ... }
},
backgroundImage: {
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
"gradient-conic":
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
},
dropShadow: {
glow: [
"0 0px 20px rgba(255,255, 255, 0.7)",
"0 0px 65px rgba(255, 255,255, 0.5)"
]
}
},
},
plugins: [],
};
export default config;

26
tsconfig.json Normal file
View File

@ -0,0 +1,26 @@
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}