From daef59ebcae02ce5de60b2a364199f2a86b7fb4e Mon Sep 17 00:00:00 2001
From: Ghian
Date: Sat, 2 Nov 2024 17:45:35 +0800
Subject: [PATCH] feat: Add skills page and enhance useObserver hook (#14)
- Created a new skills page with additional skills.
- Refactored `useObserver` hook to observe elements only once on initial page load.
- Added visibility property for education and experience sections.
---
src/components/common/hint.tsx | 2 +-
.../common}/skill-icon.tsx | 6 +-
src/components/header/sheet-menu.tsx | 61 +++++++++----
src/components/header/spread-menu.tsx | 11 ++-
src/constants/skills.ts | 42 +++++++++
src/lib/hooks/useObserver.tsx | 20 +++--
src/lib/hooks/useVisibility.tsx | 16 ++--
src/pages/root/_components/contact/index.tsx | 4 +-
.../root/_components/education/index.tsx | 2 +-
.../root/_components/experience/index.tsx | 2 +-
src/pages/root/_components/skills/backend.tsx | 12 ++-
.../root/_components/skills/frontend.tsx | 12 ++-
src/pages/root/_components/skills/index.tsx | 10 ++-
src/pages/root/_components/skills/others.tsx | 12 ++-
src/pages/root/_components/skills/tools.tsx | 12 ++-
src/pages/skills/page.tsx | 86 +++++++++++++++++++
src/routes/app-routes.ts | 1 +
src/routes/router.tsx | 4 +
18 files changed, 268 insertions(+), 47 deletions(-)
rename src/{pages/root/_components/skills => components/common}/skill-icon.tsx (75%)
create mode 100644 src/pages/skills/page.tsx
diff --git a/src/components/common/hint.tsx b/src/components/common/hint.tsx
index 95a75c5..2fc764a 100644
--- a/src/components/common/hint.tsx
+++ b/src/components/common/hint.tsx
@@ -3,7 +3,7 @@ import {
TooltipContent,
TooltipProvider,
TooltipTrigger,
-} from "../shadcn/tooltip";
+} from "@/components/shadcn/tooltip";
interface HintProps {
children: React.ReactNode;
diff --git a/src/pages/root/_components/skills/skill-icon.tsx b/src/components/common/skill-icon.tsx
similarity index 75%
rename from src/pages/root/_components/skills/skill-icon.tsx
rename to src/components/common/skill-icon.tsx
index 3105b7a..9e68b55 100644
--- a/src/pages/root/_components/skills/skill-icon.tsx
+++ b/src/components/common/skill-icon.tsx
@@ -6,15 +6,17 @@ import { cn } from "@/lib/utils";
interface SkillIconProps {
Icon: IconType;
hexColor: string;
+ ariaHidden?: React.AriaAttributes["aria-hidden"];
}
-const SkillIcon = ({ Icon, hexColor }: SkillIconProps) => {
+const SkillIcon = ({ Icon, hexColor, ariaHidden }: SkillIconProps) => {
const [hovered, setHovered] = useState(false);
return (
setHovered(true)}
diff --git a/src/components/header/sheet-menu.tsx b/src/components/header/sheet-menu.tsx
index 25fc34b..1c90fb8 100644
--- a/src/components/header/sheet-menu.tsx
+++ b/src/components/header/sheet-menu.tsx
@@ -1,4 +1,6 @@
-import { LucideMenu } from "lucide-react";
+import { Link, useLocation } from "react-router-dom";
+import { LucideMenu, MoveLeft } from "lucide-react";
+import { useEffect, useState } from "react";
import { useLenis } from "lenis/react";
import {
@@ -12,6 +14,8 @@ import {
} from "@/components/shadcn/sheet";
import { Button } from "@/components/shadcn/button";
import { ROOTMENU } from "@/constants/collections";
+import { useResize } from "@/lib/hooks/useResize";
+import { AppRoutes } from "@/routes/app-routes";
import { Hint } from "@/components/common/hint";
import { cn } from "@/lib/utils";
@@ -23,6 +27,15 @@ interface SheetMenuProps {
const SheetMenu = ({ active }: SheetMenuProps) => {
const lenis = useLenis();
+ const location = useLocation();
+ const [open, setOpen] = useState(false);
+ const { width } = useResize();
+
+ useEffect(() => {
+ if (width > 1024) {
+ setOpen(false);
+ }
+ }, [width]);
const onOpenChange = (open: boolean) => {
if (open) {
@@ -44,12 +57,19 @@ const SheetMenu = ({ active }: SheetMenuProps) => {
};
return (
-
+ {
+ onOpenChange(open);
+ setOpen(open);
+ }}
+ >
+
+ View All
+
diff --git a/src/pages/root/_components/skills/others.tsx b/src/pages/root/_components/skills/others.tsx
index 7d989da..69158f7 100644
--- a/src/pages/root/_components/skills/others.tsx
+++ b/src/pages/root/_components/skills/others.tsx
@@ -2,7 +2,7 @@ import { useVisibility } from "@/lib/hooks/useVisibility";
import { OTHERS } from "@/constants/skills";
import { cn } from "@/lib/utils";
-import { SkillIcon } from "./skill-icon";
+import { SkillIcon } from "../../../../components/common/skill-icon";
const Others = () => {
const { isVisible } = useVisibility();
@@ -15,13 +15,21 @@ const Others = () => {
!isVisible && "paused"
)}
>
- {OTHERS.concat(OTHERS).map((o, i) => (
+ {OTHERS.map((o, i) => (
))}
+ {OTHERS.map((o, i) => (
+
+ ))}
);
diff --git a/src/pages/root/_components/skills/tools.tsx b/src/pages/root/_components/skills/tools.tsx
index 4680de6..6de5c0d 100644
--- a/src/pages/root/_components/skills/tools.tsx
+++ b/src/pages/root/_components/skills/tools.tsx
@@ -2,7 +2,7 @@ import { useVisibility } from "@/lib/hooks/useVisibility";
import { TOOLS } from "@/constants/skills";
import { cn } from "@/lib/utils";
-import { SkillIcon } from "./skill-icon";
+import { SkillIcon } from "../../../../components/common/skill-icon";
const Tools = () => {
const { isVisible } = useVisibility();
@@ -15,13 +15,21 @@ const Tools = () => {
!isVisible && "paused"
)}
>
- {TOOLS.concat([...TOOLS, ...TOOLS]).map((t, i) => (
+ {TOOLS.map((t, i) => (
))}
+ {TOOLS.map((t, i) => (
+
+ ))}
);
diff --git a/src/pages/skills/page.tsx b/src/pages/skills/page.tsx
new file mode 100644
index 0000000..1d59553
--- /dev/null
+++ b/src/pages/skills/page.tsx
@@ -0,0 +1,86 @@
+import { MoveLeft } from "lucide-react";
+import { Link } from "react-router-dom";
+
+import { SkillIcon } from "@/components/common/skill-icon";
+import { AppRoutes } from "@/routes/app-routes";
+import { BACKEND, FRONTEND, OTHERS, TOOLS } from "@/constants/skills";
+
+const SkillsPage = () => {
+ return (
+
+
+ Go home
+
+
+
+
+ SKILLS
+
+
+ Innovate, Implement, Repeat.
+
+
+ Showcasing the skills I've developed and refined over the past 3
+ years.
+
+
+
+ FRONTEND
+
+
+ {FRONTEND.map((f, i) => (
+
+ ))}
+
+
+
+ BACKEND
+
+
+ {BACKEND.map((b, i) => (
+
+ ))}
+
+
+
+ OTHERS
+
+
+ {OTHERS.map((o, i) => (
+
+ ))}
+
+
+
+ TOOLS
+
+
+ {TOOLS.map((t, i) => (
+
+ ))}
+
+
+
+ );
+};
+
+export { SkillsPage };
diff --git a/src/routes/app-routes.ts b/src/routes/app-routes.ts
index 13d4abd..f9c434b 100644
--- a/src/routes/app-routes.ts
+++ b/src/routes/app-routes.ts
@@ -2,4 +2,5 @@ export const enum AppRoutes {
root = "/",
notFound = "*",
github404 = "/404",
+ skills = "/skills",
}
diff --git a/src/routes/router.tsx b/src/routes/router.tsx
index 0d978ae..9713ec0 100644
--- a/src/routes/router.tsx
+++ b/src/routes/router.tsx
@@ -5,6 +5,7 @@ import {
} from "react-router-dom";
import NotFoundPage from "@/pages/not-found/page";
+import { SkillsPage } from "@/pages/skills/page";
import RootLayout from "@/pages/root/layout";
import ErrorPage from "@/pages/error/page";
import RootPage from "@/pages/root/page";
@@ -21,6 +22,9 @@ export const router = createBrowserRouter(
{/* Root */}
} />
+ {/* Skills */}
+ } />
+
{/* Github 404 */}
} />