Skip to content

Commit

Permalink
add contact section, resend, navbar follow active section, new web icon.
Browse files Browse the repository at this point in the history
  • Loading branch information
kudanilll committed Jun 9, 2024
1 parent 0bba4c4 commit 8a69723
Show file tree
Hide file tree
Showing 28 changed files with 7,676 additions and 3,216 deletions.
3 changes: 2 additions & 1 deletion env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
NEXT_PUBLIC_DOMAIN=
CV_URL_DOWNLOAD=
CV_URL_DOWNLOAD=
RESEND_API_KEY=
10,458 changes: 7,308 additions & 3,150 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@
"format": "prettier --write --ignore-path=.gitignore ."
},
"dependencies": {
"@react-email/components": "^0.0.19",
"@react-email/render": "^0.0.15",
"@tailwindcss/typography": "^0.5.10",
"framer-motion": "^9.1.7",
"hamburger-react": "^2.5.0",
"next": "^14.2.3",
"nextjs-toploader": "^1.6.4",
"react": "^18",
"react-dom": "^18",
"react-email": "^2.1.4",
"react-hot-toast": "^2.4.1",
"react-icons": "^5.2.1",
"react-intersection-observer": "^9.10.3",
"react-typed": "^2.0.12",
"resend": "^3.2.0",
Expand Down
Binary file modified public/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/favicon.ico
Binary file not shown.
Binary file modified public/icon-192-maskable.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/icon-192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/icon-512-maskable.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/icon-512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/web-icon.png
Binary file not shown.
File renamed without changes.
21 changes: 11 additions & 10 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import type { Metadata } from "next";
import { SeoMetadata } from "@/utils/seo-metadata";
import { Toaster } from "react-hot-toast";
import { Noto_Sans } from "next/font/google";
import NextTopLoader from "nextjs-toploader";
import NavigationBar from "@/components/ui/navbar";
import ActiveSectionContextProvider from "@/context/active-section-context";
import "@/styles/globals.css";
import ThemeContextProvider from "@/context/theme-context";
import "./globals.css";

const notoSans = Noto_Sans({
subsets: ["latin"],
Expand All @@ -24,14 +24,15 @@ export default function RootLayout({
className="scroll-smooth"
style={{ scrollBehavior: "smooth" }}>
<body className={notoSans.className}>
<ActiveSectionContextProvider>
<nav>
<NextTopLoader color="#0284C7" showSpinner={false} />
<NavigationBar />
</nav>
{children}
<Toaster position="bottom-right" />
</ActiveSectionContextProvider>
<ThemeContextProvider>
<ActiveSectionContextProvider>
<header>
<NavigationBar />
</header>
{children}
<Toaster position="bottom-right" />
</ActiveSectionContextProvider>
</ThemeContextProvider>
</body>
</html>
);
Expand Down
43 changes: 22 additions & 21 deletions src/app/not-found.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,33 @@ export const metadata: Metadata = {
metadataBase: new URL(
process.env.NEXT_PUBLIC_DOMAIN || "http://localhost:3000"
),
title: "Not Found | Achmad Daniel",
title: "Achmad Daniel | Not Found",
description: "Halaman Tidak Ditemukan",
};

export default function NotFound() {
return (
<div className="flex flex-col h-screen bg-slate-100 text-black">
<div className="text-center justify-center items-center content-center space-y-4">
<Link
href="https://www.freepik.com/free-vector/oops-404-error-with-broken-robot-concept-illustration_8030430.htm#fromView=search&page=1&position=31&uuid=10c64f8c-0de7-40fa-8cb0-5baa7d625b32"
target="_blank"
aria-label="Image by storyset on Freepik"
className=" flex justify-center items-center">
<Image
src="/assets/not-found.png"
alt="Image by storyset on Freepik"
data-aos="fade-up"
height={300}
width={300}
/>
</Link>
<h1 className="text-2xl font-semibold">404 - Page not found :(</h1>
<p>The page you are looking for does not exist</p>
<div className="mt-4 flex justify-center items-center">
<Button text="GO HOME" url={process.env.NEXT_PUBLIC_DOMAIN} />
</div>
<div className="flex flex-col min-h-screen h-screen bg-slate-100 text-black text-center justify-center items-center content-center space-y-4">
<Link
href="https://www.freepik.com/free-vector/oops-404-error-with-broken-robot-concept-illustration_8030430.htm#fromView=search&page=1&position=31&uuid=10c64f8c-0de7-40fa-8cb0-5baa7d625b32"
target="_blank"
aria-label="Image by storyset on Freepik"
className=" flex justify-center items-center">
<Image
src="/assets/not-found.png"
alt="Image by storyset on Freepik"
data-aos="fade-up"
height={300}
width={300}
priority
/>
</Link>
<h1 className="text-2xl font-semibold">404 - Page not found :(</h1>
<p>The page you are looking for does not exist</p>
<div className="mt-4 flex justify-center items-center">
<Button label="Return to home" url={process.env.NEXT_PUBLIC_DOMAIN}>
GO HOME
</Button>
</div>
</div>
);
Expand Down
39 changes: 39 additions & 0 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,50 @@
"use client";
import { useEffect } from "react";
import { useActiveSectionContext } from "@/context/active-section-context";
import Home from "@/components/section/home";
import About from "@/components/section/about";
import Skills from "@/components/section/skills";
import Contact from "@/components/section/contact";
import Footer from "@/components/ui/footer";

export default function HomePage() {
const { activeSection, setActiveSection } = useActiveSectionContext();
useEffect(() => {
const home = document.getElementById("home");
const about = document.getElementById("about");
const skills = document.getElementById("skills");
const contact = document.getElementById("contact");
const sections = [home, about, skills, contact];

const observerOptions = {
root: null,
rootMargin: "0px",
threshold: 0.5,
};

const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
if (entry.target.id == "home") {
setActiveSection("Home");
}
if (entry.target.id == "about") {
setActiveSection("About");
}
if (entry.target.id == "skills") {
setActiveSection("Skills");
}
if (entry.target.id == "contact") {
setActiveSection("Contact");
}
}
});
}, observerOptions);

sections?.forEach((section) => {
section && observer.observe(section);
});
}, [setActiveSection]);
return (
<>
<main className="flex flex-col min-h-screen bg-slate-100 text-black">
Expand Down
43 changes: 43 additions & 0 deletions src/components/email/contact-email-form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {
Html,
Body,
Head,
Heading,
Hr,
Container,
Preview,
Section,
Text,
} from "@react-email/components";
import { Tailwind } from "@react-email/tailwind";

type ContactEmailFormProps = {
message: string;
senderEmail: string;
};

export default function ContactEmailForm({
message,
senderEmail,
}: ContactEmailFormProps) {
return (
<Html>
<Head />
<Preview>New message from your portfolio site</Preview>
<Tailwind>
<Body className="bg-gray-100 text-black">
<Container>
<Section className="bg-white borderBlack my-10 px-10 py-4 rounded-md">
<Heading className="leading-tight">
You received the following message from the contact form
</Heading>
<Text>{message}</Text>
<Hr />
<Text>{`The sender's email is: ${senderEmail}`}</Text>
</Section>
</Container>
</Body>
</Tailwind>
</Html>
);
}
7 changes: 6 additions & 1 deletion src/components/section/about.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,12 @@ export default function About() {
viewport={{
once: true,
}}>
<Button text="Next" color="border-2 border-white" url="#skills" />
<Button
label="Next to skills page"
color="border-2 border-white"
url="#skills">
NEXT
</Button>
</motion.div>
</div>
<div className="hidden md:flex justify-center items-center pt-16 content-center">
Expand Down
83 changes: 80 additions & 3 deletions src/components/section/contact.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,92 @@
"use client";
import { useSection } from "@/hooks/use-section";
import { motion } from "framer-motion";
import { sendEmail } from "@/services/send-email";
import React from "react";
import toast from "react-hot-toast";
import Title from "@/components/typography/title";
import SectionWrapper from "@/components/ui/section-wrapper";
import { useSection } from "@/hooks/use-section";
import SubmitButton from "@/components/ui/submit-button";

export default function Contact() {
const { ref } = useSection("Contact");
return (
<SectionWrapper ref={ref} id="contact">
<div className="px-12 flex w-full h-screen justify-center items-center flex-col md:flex-row md:mx-auto bg-sky-700 text-white">
<Title text="Contact" />
<div className="px-12 flex w-full h-screen justify-center items-center flex-col md:mx-auto bg-sky-700 text-white">
<motion.div
initial={{ opacity: 0, y: 100 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{
type: "spring",
stiffness: 125,
duration: 0.7,
delay: 0.2,
}}
viewport={{
once: true,
}}>
<Title text="Contact" />
</motion.div>
<motion.p
className="max-w-xl mt-2 text-center"
initial={{ opacity: 0, y: 100 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{
type: "spring",
stiffness: 125,
duration: 0.7,
delay: 0.2,
}}
viewport={{
once: true,
}}>
If you have a specific question or comment, please feel free to email
me directly at{" "}
<a className="underline" href="mailto:achmad24daniel@gmail.com">
achmad24daniel@gmail.com
</a>{" "}
or through this form.
</motion.p>
<motion.form
className="mt-6 flex flex-col dark:text-black"
initial={{ opacity: 0, y: 100 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{
type: "spring",
stiffness: 125,
duration: 0.7,
delay: 0.2,
}}
viewport={{
once: true,
}}
action={async (formData) => {
const { error } = await sendEmail(formData);
if (error) {
toast.error(error);
return;
}
toast.success("Email sent successfully!");
}}>
<input
className="h-14 px-4 rounded-lg border-2 focus:border-sky-300 transition-all dark:outline-none"
style={{ width: "400px" }}
name="senderEmail"
type="email"
required
maxLength={50}
placeholder="Your email"
/>
<textarea
className="h-40 my-3 rounded-lg border-2 focus:border-sky-300 p-4 transition-all dark:outline-none"
style={{ width: "400px" }}
name="message"
placeholder="Your message"
required
maxLength={1000}
/>
<SubmitButton />
</motion.form>
</div>
</SectionWrapper>
);
Expand Down
15 changes: 9 additions & 6 deletions src/components/section/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export default function Home() {
</div>
<div className="mt-6 flex justify-center md:justify-start">
<motion.div
className="md:mr-4"
className="mr-1.5 md:mr-4"
initial={{ opacity: 0, scale: 0 }}
animate={{ opacity: 1, scale: 1 }}
transition={{
Expand All @@ -81,10 +81,11 @@ export default function Home() {
delay: 0.3,
}}>
<Button
text="Hire Me"
color="bg-pink-500 hover:bg-pink-800 duration-300"
url="mailto:achmad24daniel@gmail.com, achmad24daniel@gmail.com?subject=I am interested in working with you."
/>
label="Hire Me"
color="bg-pink-500 hover:bg-pink-600 duration-300"
url="mailto:achmad24daniel@gmail.com, achmad24daniel@gmail.com?subject=I am interested in working with you.">
Hire Me
</Button>
</motion.div>
<motion.div
initial={{ opacity: 0, scale: 0 }}
Expand All @@ -94,7 +95,9 @@ export default function Home() {
duration: 0.3,
delay: 0.3,
}}>
<Button text="Download CV" url={process.env.CV_URL_DOWNLOAD} />
<Button label="Download CV" url={process.env.CV_URL_DOWNLOAD}>
Download CV
</Button>
</motion.div>
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions src/components/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export default function Button(props: any) {
whileTap={{
scale: 0.9,
}}>
<Link href={props.url ?? ""} aria-label={props.text}>
<Link href={props.url ?? "/"} aria-label={props.label ? props.label : ""}>
<div
aria-label={props.text}
aria-label={props.label ? props.label : ""}
className={`rounded-xl mr-2 hover:drop-shadow ${
props.color ??
"bg-sky-700 md:bg-gray-300 hover:bg-sky-700 duration-300"
Expand All @@ -24,7 +24,7 @@ export default function Button(props: any) {
? "text-white"
: "text-white md:text-neutral-700 hover:text-white duration-300"
}`}>
{props.text ?? ""}
{props.children}
</p>
</div>
</Link>
Expand Down
4 changes: 2 additions & 2 deletions src/components/ui/footer.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export default function Footer() {
return (
<footer className="pb-8 px-4 text-center bg-sky-700 text-white select-none">
<small className="mb-2 block text-xs">
<footer className="pb-4 px-4 text-center bg-sky-700 text-white select-none">
<small className="block text-xs">
&copy; {new Date().getFullYear()} Achmad Daniel Syahputra. All rights
reserved.
</small>
Expand Down
Loading

0 comments on commit 8a69723

Please sign in to comment.