Skip to content

Commit

Permalink
Update lazy loading content of each section, and resolving conflicts …
Browse files Browse the repository at this point in the history
…of lazy loading and navigation
  • Loading branch information
giaphm committed Jun 13, 2024
1 parent 9d6fe51 commit 36331db
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 109 deletions.
24 changes: 8 additions & 16 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
import { lazy } from "react";
import { Experiences } from "./components/experiences";
import { Footer } from "./components/footer";
const Introduction = lazy(() => import("./components/introduction"));
const AboutMe = lazy(() => import("./components/aboutMe"));
const NavBar = lazy(() => import("./components/navBar"));
const Projects = lazy(() => import("./components/projects"));
const Skills = lazy(() => import("./components/skills"));
import { SmoothScrollProgressBar } from "./components/smooth-scroll-progressbar";
import { RenderOnViewportEntry } from "./components/renderOnViewportEntry";
import AboutMe from "./components/aboutMe";
import Projects from "./components/projects";
import Skills from "./components/skills";
import NavBar from "./components/navBar";
import Introduction from "./components/introduction";

function App() {
return (
<>
<SmoothScrollProgressBar />
<NavBar />
<Introduction />
<RenderOnViewportEntry threshold={0.25} style={{ minHeight: "240px" }}>
<AboutMe />
</RenderOnViewportEntry>
<RenderOnViewportEntry threshold={0.25} style={{ minHeight: "240px" }}>
<Projects />
</RenderOnViewportEntry>
<RenderOnViewportEntry threshold={0.25} style={{ minHeight: "240px" }}>
<Skills />
</RenderOnViewportEntry>
<AboutMe />
<Projects />
<Skills />
<Experiences />
<Footer />
</>
Expand Down
65 changes: 38 additions & 27 deletions src/components/aboutMe.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,13 @@ import Icons from "./icons";
import { useHandleScrollAnchor } from "~/hooks/useHandleScrollAnchor";
import { Link } from "react-router-dom";
import { motion } from "framer-motion";
import { RenderOnViewportEntry } from "./renderOnViewportEntry";

export default function AboutMe() {
function AboutMeBody() {
const { t } = useTranslation();
const handleScrollAnchor = useHandleScrollAnchor();

return (
<section id="aboutMe" className="pb-12 dark:bg-[#1F1F1F]">
<h2 className="pt-12 text-center font-light">
<div className="flex flex-row justify-center items-center gap-x-2 group">
<div className="relative">
<Link
to={"#aboutMe"}
className="cursor-pointer font-open-sans 2xl:text-4xl"
onClick={() => handleScrollAnchor("#aboutMe")}
>
{t("aboutMe.title").toLocaleUpperCase()}
</Link>
<Link
to={"#aboutMe"}
className="absolute left-full opacity-0 group-hover:opacity-100 cursor-pointer"
onClick={() => handleScrollAnchor("#aboutMe")}
>
<Icons.iconify
icon="system-uicons:chain"
width="22"
height="22"
/>
</Link>
</div>
</div>
</h2>
<RenderOnViewportEntry threshold={0.25} style={{ minHeight: "240px" }}>
<motion.div
initial={"init"}
whileInView={"show"}
Expand Down Expand Up @@ -100,6 +76,41 @@ export default function AboutMe() {
</div>
</div>
</motion.div>
</RenderOnViewportEntry>
);
}

export default function AboutMe() {
const { t } = useTranslation();
const handleScrollAnchor = useHandleScrollAnchor();

return (
<section id="aboutMe" className="pb-12 dark:bg-[#1F1F1F]">
<h2 className="pt-12 text-center font-light">
<div className="flex flex-row justify-center items-center gap-x-2 group">
<div className="relative">
<Link
to={"#aboutMe"}
className="cursor-pointer font-open-sans 2xl:text-4xl"
onClick={() => handleScrollAnchor("#aboutMe")}
>
{t("aboutMe.title").toLocaleUpperCase()}
</Link>
<Link
to={"#aboutMe"}
className="absolute left-full opacity-0 group-hover:opacity-100 cursor-pointer"
onClick={() => handleScrollAnchor("#aboutMe")}
>
<Icons.iconify
icon="system-uicons:chain"
width="22"
height="22"
/>
</Link>
</div>
</div>
</h2>
<AboutMeBody />
</section>
);
}
74 changes: 46 additions & 28 deletions src/components/projects.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,48 @@ import { useHandleScrollAnchor } from "~/hooks/useHandleScrollAnchor";
import { Link } from "react-router-dom";
import { CardProject } from "./cardProject";
import { motion, useCycle } from "framer-motion";
import { RenderOnViewportEntry } from "./renderOnViewportEntry";

function ProjectBody({
projects,
onHandleShowModal,
}: {
projects: ProjectType[];
onHandleShowModal: (project: ProjectType) => void;
}) {
return (
<RenderOnViewportEntry threshold={0.25} style={{ minHeight: "240px" }}>
<motion.div
initial={"init"}
whileInView={"show"}
variants={{
init: { opacity: 0, scale: 0.8 },
show: {
opacity: 1,
scale: 1,
transition: {
ease: "linear",
duration: 0.5,
},
},
}}
>
<div className="grid grid-cols-1 md:grid-cols-2 md:gap-x-5 xl:grid-cols-3 px-5">
{projects.map((project, idx) => (
<CardProject
key={idx}
title={project.title.toLocaleUpperCase()}
description={project.desc}
thumbnail={project.images[0]}
repoLink={project.repoLink}
onOpenSlide={() => onHandleShowModal(project)}
/>
))}
</div>
</motion.div>
</RenderOnViewportEntry>
);
}

export default function Projects() {
const { t } = useTranslation();
Expand Down Expand Up @@ -53,34 +95,10 @@ export default function Projects() {
</div>
</div>
</h2>
<motion.div
initial={"init"}
whileInView={"show"}
variants={{
init: { opacity: 0, scale: 0.8 },
show: {
opacity: 1,
scale: 1,
transition: {
ease: "linear",
duration: 0.5,
},
},
}}
>
<div className="grid grid-cols-1 md:grid-cols-2 md:gap-x-5 xl:grid-cols-3 px-5">
{projects.map((project, idx) => (
<CardProject
key={idx}
title={project.title.toLocaleUpperCase()}
description={project.desc}
thumbnail={project.images[0]}
repoLink={project.repoLink}
onOpenSlide={() => onHandleShowModal(project)}
/>
))}
</div>
</motion.div>
<ProjectBody
projects={projects}
onHandleShowModal={onHandleShowModal}
/>
</div>
<ProjectSlideModal
show={isOpenModal}
Expand Down
1 change: 0 additions & 1 deletion src/components/renderOnViewportEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export const RenderOnViewportEntry = ({
rootMargin = "0px 0px 0px 0px",
...wrapperDivProps
}: RenderOnViewportEntryType) => {
console.log("wrapperDivProps", wrapperDivProps);
const ref = useRef(null);
const entered = useFirstViewportEntry(ref, { threshold, root, rootMargin });

Expand Down
71 changes: 40 additions & 31 deletions src/components/skills.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,14 @@
import { useTranslation } from "react-i18next";
import { useLoadSkills } from "~/hooks/useLoadSkills";
import { SkillType, useLoadSkills } from "~/hooks/useLoadSkills";
import Icons from "./icons";
import { Link } from "react-router-dom";
import { useHandleScrollAnchor } from "~/hooks/useHandleScrollAnchor";
import { motion } from "framer-motion";
import { RenderOnViewportEntry } from "./renderOnViewportEntry";

export default function Skills() {
const { t } = useTranslation();
const skills = useLoadSkills();
const handleScrollAnchor = useHandleScrollAnchor();

function SkillsBody({ skills }: { skills: SkillType[] }) {
return (
<section id="skills" className="bg-[#1f1f1f] pb-[10%]">
<h2 className="text-white text-center font-light py-12">
<div className="flex flex-row justify-center items-center gap-x-2 group">
<div className="relative">
<Link
to={"#skills"}
className="cursor-pointer font-open-sans 2xl:text-4xl"
onClick={() => handleScrollAnchor("#skills")}
>
{t("skills.title").toLocaleUpperCase()}
</Link>
<Link
to={"#skills"}
className="absolute left-full opacity-0 group-hover:opacity-100 cursor-pointer"
onClick={() => handleScrollAnchor("#skills")}
>
<Icons.iconify
icon="system-uicons:chain"
width="22"
height="22"
/>
</Link>
</div>
</div>
</h2>
<RenderOnViewportEntry threshold={0.25} style={{ minHeight: "240px" }}>
<motion.div
initial={"init"}
whileInView={"show"}
Expand Down Expand Up @@ -69,6 +42,42 @@ export default function Skills() {
))}
</ul>
</motion.div>
</RenderOnViewportEntry>
);
}

export default function Skills() {
const { t } = useTranslation();
const skills = useLoadSkills();
const handleScrollAnchor = useHandleScrollAnchor();

return (
<section id="skills" className="bg-[#1f1f1f] pb-[10%]">
<h2 className="text-white text-center font-light py-12">
<div className="flex flex-row justify-center items-center gap-x-2 group">
<div className="relative">
<Link
to={"#skills"}
className="cursor-pointer font-open-sans 2xl:text-4xl"
onClick={() => handleScrollAnchor("#skills")}
>
{t("skills.title").toLocaleUpperCase()}
</Link>
<Link
to={"#skills"}
className="absolute left-full opacity-0 group-hover:opacity-100 cursor-pointer"
onClick={() => handleScrollAnchor("#skills")}
>
<Icons.iconify
icon="system-uicons:chain"
width="22"
height="22"
/>
</Link>
</div>
</div>
</h2>
<SkillsBody skills={skills} />
</section>
);
}
1 change: 0 additions & 1 deletion src/hooks/useFirstViewportEntry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export function useFirstViewportEntry(
const [entered, setEntered] = useState<boolean>(false);
const observer = useRef(
new IntersectionObserver(([entry]) => {
console.log("entry.isIntersecting", entry.isIntersecting);
setEntered(entry.isIntersecting);
}, observerOptions),
);
Expand Down
8 changes: 4 additions & 4 deletions src/hooks/useHandleScrollAnchor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ export function useHandleScrollAnchor() {
const id = href.substring(href.indexOf("#") + 1);
const anchorDOM = document.getElementById(id);
if (anchorDOM) {
const yOffset = -80;
const y =
anchorDOM.getBoundingClientRect().top + window.scrollY + yOffset;
window.scrollTo({ top: y, behavior: "smooth" });
setTimeout(() => {
anchorDOM.scrollIntoView(true);
window.scrollBy({ top: -80, left: 0, behavior: "smooth" });
}, 100);
}
}, []);

Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useLoadSkills.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useState } from "react";

type SkillType = {
export type SkillType = {
skillName: string;
icon: string;
};
Expand Down

0 comments on commit 36331db

Please sign in to comment.