diff --git a/src/components/ProjectCards.tsx b/src/components/ProjectCards.tsx
index c1db3c1..9c18ae9 100644
--- a/src/components/ProjectCards.tsx
+++ b/src/components/ProjectCards.tsx
@@ -9,7 +9,7 @@ const ProjectCards = ({ projects }: { projects: PaginatedDocs }) => {
const [tooltipText, setTooltipText] = useState("i like kway teow");
const [isTooltipShow, setTooltipShow] = useState(false);
- const tooltipHandler: MouseTooltipHandler = {
+ const tooltipHandler: IMouseTooltipHandler = {
updateText: (text: string) => setTooltipText(text),
updateVisibility: (show: boolean) => setTooltipShow(show),
};
diff --git a/src/models/common.types.d.ts b/src/models/common.types.d.ts
index 23b8b5e..84ec575 100644
--- a/src/models/common.types.d.ts
+++ b/src/models/common.types.d.ts
@@ -1,6 +1,6 @@
import { ReactElement, ReactNode } from "react";
-interface BaseChildrenProps {
+interface IBaseChildrenProps {
children?: ReactNode | ReactElement | string,
}
diff --git a/src/models/mouse-tooltip.types.d.ts b/src/models/mouse-tooltip.types.d.ts
index b9a1829..344674f 100644
--- a/src/models/mouse-tooltip.types.d.ts
+++ b/src/models/mouse-tooltip.types.d.ts
@@ -1,4 +1,4 @@
-interface MouseTooltipHandler {
+interface IMouseTooltipHandler {
updateText: (_text: string) => void,
updateVisibility: (_show: boolean) => void,
}
From 2ff637bd7f8620881b892bff4c79e5c2d2ea9f76 Mon Sep 17 00:00:00 2001
From: ItsLame <37344470+ItsLame@users.noreply.github.com>
Date: Mon, 9 Jun 2025 17:43:41 +1000
Subject: [PATCH 04/10] feat: hide tooltip on mobile
---
src/components/MouseTooltip.tsx | 2 +-
src/models/mouse-tooltip.types.d.ts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/components/MouseTooltip.tsx b/src/components/MouseTooltip.tsx
index 57eaead..6591308 100644
--- a/src/components/MouseTooltip.tsx
+++ b/src/components/MouseTooltip.tsx
@@ -27,7 +27,7 @@ const MouseTooltip = ({ children, show }: IMouseTooltipProps) => {
return (
-
{children}
diff --git a/src/models/mouse-tooltip.types.d.ts b/src/models/mouse-tooltip.types.d.ts
index 344674f..444fba1 100644
--- a/src/models/mouse-tooltip.types.d.ts
+++ b/src/models/mouse-tooltip.types.d.ts
@@ -1,4 +1,4 @@
interface IMouseTooltipHandler {
updateText: (_text: string) => void,
- updateVisibility: (_show: boolean) => void,
+ updateVisibility: (_visibility: boolean) => void,
}
From 19dcb34605c7488508a03fc53a08b739a993e831 Mon Sep 17 00:00:00 2001
From: ItsLame <37344470+ItsLame@users.noreply.github.com>
Date: Mon, 9 Jun 2025 19:16:03 +1000
Subject: [PATCH 05/10] refactor: map links to component instead
---
eslint.config.mjs | 3 +-
src/components/ProjectCard.tsx | 85 +++++++++++++++++++---------------
2 files changed, 49 insertions(+), 39 deletions(-)
diff --git a/eslint.config.mjs b/eslint.config.mjs
index 8426c92..f311531 100644
--- a/eslint.config.mjs
+++ b/eslint.config.mjs
@@ -15,7 +15,8 @@ const eslintConfig = [
rules: {
"indent": ["error", 2],
"eol-last": ["error", "always"],
- "no-unused-vars": ["error", {
+ "no-unused-vars": "off",
+ "@typescript-eslint/no-unused-vars": ["error", {
"argsIgnorePattern": "^_",
}],
"no-trailing-spaces": "error",
diff --git a/src/components/ProjectCard.tsx b/src/components/ProjectCard.tsx
index 55481f3..ecb9e5a 100644
--- a/src/components/ProjectCard.tsx
+++ b/src/components/ProjectCard.tsx
@@ -1,14 +1,16 @@
import { IconBrandYoutube, IconBrush, IconCode, IconExternalLink, IconFile, IconPlayerPlay } from "@tabler/icons-react";
-import React from "react";
+import React, { ReactNode } from "react";
import Link from "next/link";
import { IBaseChildrenProps, NullableString } from "@/models";
interface IProjectTagProps extends IBaseChildrenProps {}
-interface IProjectLinkProps extends IBaseChildrenProps {
+interface IProjectLinkProps {
link: string,
+ linkText: string,
+ icon?: ReactNode,
newTab?: true,
- tooltipHandler?: IMouseTooltipHandler
+ tooltipHandler?: IMouseTooltipHandler,
}
interface IProjectCardProps {
@@ -31,20 +33,21 @@ const ProjectTag = ({ children }: IProjectTagProps) => {
);
};
-const ProjectLink = ({ children, link, newTab, tooltipHandler }: IProjectLinkProps) => {
+const ProjectLink = ({ link, linkText, icon, newTab, tooltipHandler }: IProjectLinkProps) => {
const handleShowTooltip = () => {
tooltipHandler?.updateVisibility(true);
- tooltipHandler?.updateText(link);
+ tooltipHandler?.updateText(`${linkText}` || "");
};
const handleHideTooltip = () => {
tooltipHandler?.updateVisibility(false);
};
- const LinkContent = ({ children }: IBaseChildrenProps) => {
+ const LinkContent = () => {
return (
- {children}
+ {icon}
+ {linkText}
);
};
@@ -54,13 +57,38 @@ const ProjectLink = ({ children, link, newTab, tooltipHandler }: IProjectLinkPro
onMouseEnter={handleShowTooltip} onMouseLeave={handleHideTooltip}
>
- {children} {newTab && }
+ {newTab && }
);
};
+
const ProjectCard = ({ title, description, repoLink, demoLink, videoLink, designLink, paperLink, techStack, tooltipHandler }: IProjectCardProps) => {
+ enum LinkType {
+ Video = "video",
+ Demo = "demo",
+ Repo = "repo",
+ Design = "design",
+ Paper = "paper"
+ }
+
+ interface IProjectCardLink {
+ type: LinkType,
+ icon: ReactNode
+ newTab?: true,
+ name?: string,
+ url?: NullableString,
+ }
+
+ const projectCardLinks: IProjectCardLink[] = [
+ { type: LinkType.Video, url: videoLink, icon:
, newTab: true },
+ { type: LinkType.Demo, url: demoLink, icon:
, newTab: true },
+ { type: LinkType.Repo, url: repoLink, name: "code", icon:
, newTab: true },
+ { type: LinkType.Design, url: designLink, icon:
, newTab: true },
+ { type: LinkType.Paper, url: paperLink, icon:
, newTab: true },
+ ];
+
return (
@@ -74,36 +102,17 @@ const ProjectCard = ({ title, description, repoLink, demoLink, videoLink, design
)}
{description}
- {videoLink &&
-
-
- video
-
- }
- {demoLink &&
-
-
- demo
-
- }
- {repoLink &&
-
-
- code
-
- }
- {designLink &&
-
-
- design
-
- }
- {paperLink &&
-
-
- paper
-
- }
+ {projectCardLinks.map(link =>
+ link.url &&
+
+ )}
From 200793c8ed92ec7fef0f98d8fbabe9b65bd363e6 Mon Sep 17 00:00:00 2001
From: ItsLame <37344470+ItsLame@users.noreply.github.com>
Date: Mon, 9 Jun 2025 21:00:58 +1000
Subject: [PATCH 06/10] feat: stylise mouse tooltip
---
src/components/MouseTooltip.tsx | 2 +-
src/components/ProjectCard.tsx | 2 +-
src/styles/components/mouse-tooltip.css | 15 +++++++++++++++
src/styles/index.css | 1 +
4 files changed, 18 insertions(+), 2 deletions(-)
create mode 100644 src/styles/components/mouse-tooltip.css
diff --git a/src/components/MouseTooltip.tsx b/src/components/MouseTooltip.tsx
index 6591308..c61e5c8 100644
--- a/src/components/MouseTooltip.tsx
+++ b/src/components/MouseTooltip.tsx
@@ -27,7 +27,7 @@ const MouseTooltip = ({ children, show }: IMouseTooltipProps) => {
return (
-
{children}
diff --git a/src/components/ProjectCard.tsx b/src/components/ProjectCard.tsx
index ecb9e5a..895aa30 100644
--- a/src/components/ProjectCard.tsx
+++ b/src/components/ProjectCard.tsx
@@ -36,7 +36,7 @@ const ProjectTag = ({ children }: IProjectTagProps) => {
const ProjectLink = ({ link, linkText, icon, newTab, tooltipHandler }: IProjectLinkProps) => {
const handleShowTooltip = () => {
tooltipHandler?.updateVisibility(true);
- tooltipHandler?.updateText(`${linkText}` || "");
+ tooltipHandler?.updateText(`${linkText}` || "view");
};
const handleHideTooltip = () => {
diff --git a/src/styles/components/mouse-tooltip.css b/src/styles/components/mouse-tooltip.css
new file mode 100644
index 0000000..fa1c5c0
--- /dev/null
+++ b/src/styles/components/mouse-tooltip.css
@@ -0,0 +1,15 @@
+.mouse-tooltip {
+ @apply absolute z-50 -ml-6 mt-10
+ drop-shadow-[0px_0px_4px_rgba(124,45,18,0.5)]
+ bg-orange-100 px-4 py-2 rounded-lg;
+}
+
+.mouse-tooltip:before {
+ content: "";
+ @apply absolute border-solid border-[12px]
+ border-b-orange-100
+ border-r-transparent
+ border-l-transparent
+ border-t-transparent
+ top-[-22px];
+}
diff --git a/src/styles/index.css b/src/styles/index.css
index 7950503..815d5c9 100644
--- a/src/styles/index.css
+++ b/src/styles/index.css
@@ -11,3 +11,4 @@
@import "components/footer.css";
@import "components/contact-links.css";
@import "components/project-card.css";
+@import "components/mouse-tooltip.css";
From fc0d972742da4ef6cd1a443265c5de5cb1147b5f Mon Sep 17 00:00:00 2001
From: ItsLame <37344470+ItsLame@users.noreply.github.com>
Date: Mon, 9 Jun 2025 21:58:40 +1000
Subject: [PATCH 07/10] feat: tooltip dark mode
---
src/styles/components/mouse-tooltip.css | 7 ++++---
src/styles/components/project-card.css | 6 ++++--
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/src/styles/components/mouse-tooltip.css b/src/styles/components/mouse-tooltip.css
index fa1c5c0..b167aac 100644
--- a/src/styles/components/mouse-tooltip.css
+++ b/src/styles/components/mouse-tooltip.css
@@ -1,13 +1,14 @@
.mouse-tooltip {
@apply absolute z-50 -ml-6 mt-10
- drop-shadow-[0px_0px_4px_rgba(124,45,18,0.5)]
- bg-orange-100 px-4 py-2 rounded-lg;
+ drop-shadow-[0px_0px_4px_rgba(124,45,18,0.5)]
+ bg-orange-100 px-4 py-2 rounded-lg
+ dark:bg-orange-900 dark:drop-shadow-[0px_0px_4px_rgba(0,0,0,0.8)];
}
.mouse-tooltip:before {
content: "";
@apply absolute border-solid border-[12px]
- border-b-orange-100
+ border-b-orange-100 dark:border-b-orange-900
border-r-transparent
border-l-transparent
border-t-transparent
diff --git a/src/styles/components/project-card.css b/src/styles/components/project-card.css
index 71bec46..d1e266f 100644
--- a/src/styles/components/project-card.css
+++ b/src/styles/components/project-card.css
@@ -6,7 +6,8 @@
@apply py-6 px-8 rounded-2xl mb-4 bg-orange-300 bg-opacity-30 transition-all
shadow-[inset_0_0_0_0_#9a3412,0_2px_4px_0_#9a3412]
hover:shadow-[inset_0_2px_4px_1px_#9a3412,0_0_0_0_#9a3412]
- hover:bg-opacity-45;
+ hover:bg-opacity-45
+ ;
.project-card-title {
@apply text-orange-800 dark:text-orange-300;
@@ -44,6 +45,7 @@
@apply transition-shadow
shadow-[inset_0_0_0_0_black,0_2px_4px_0_black]
hover:shadow-[inset_0_2px_4px_1px_black,0_0_0_0_black]
- hover:bg-opacity-15;
+ hover:bg-opacity-15
+ ;
}
}
From 7d6284a548ba1c13ae156d4533e3275df4120f88 Mon Sep 17 00:00:00 2001
From: ItsLame <37344470+ItsLame@users.noreply.github.com>
Date: Mon, 9 Jun 2025 21:58:51 +1000
Subject: [PATCH 08/10] chore: clean up
---
src/components/Navbar.tsx | 5 +----
src/styles/components/navbar.css | 14 +++++++++-----
2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx
index b7780dc..d4611c5 100644
--- a/src/components/Navbar.tsx
+++ b/src/components/Navbar.tsx
@@ -20,9 +20,7 @@ const NavbarLink = ({ children, className = "", link = "", newTab } : {children?
const Navbar = () => {
const [isBurgerOpened, setIsBurgerOpened] = useState(false);
- const handleBurgerClick = () => {
- setIsBurgerOpened(!isBurgerOpened);
- };
+ const handleBurgerClick = () => setIsBurgerOpened(!isBurgerOpened);
return (
);
diff --git a/src/styles/components/navbar.css b/src/styles/components/navbar.css
index fc08e37..0f11a0b 100644
--- a/src/styles/components/navbar.css
+++ b/src/styles/components/navbar.css
@@ -14,9 +14,10 @@
}
.navbar .logo .burger-menu {
- @apply font-semibold md:hidden;
+ @apply font-semibold md:hidden
+ transition-colors ease-in-out duration-200;
- &:hover,
+ /*&:hover,*/
&.opened {
@apply text-red-600 dark:text-red-300;
}
@@ -28,18 +29,21 @@
transition-[max-height,margin-top] duration-300;
&:not(&.opened) {
- @apply h-0 max-h-0 md:h-full md:max-h-full;
+ @apply h-0 md:h-full
+ max-h-0 md:max-h-full
+ transition-[max-height,margin-top] duration-300;
}
&.opened {
- @apply max-h-60 mt-4
+ @apply h-full
+ max-h-60 mt-4
md:max-h-full md:mt-0
transition-[max-height,margin-top] duration-300;
}
a.menu-link {
@apply flex gap-1 py-2 px-4 rounded-full
- transition ease-in-out duration-200 font-semibold;
+ transition-colors ease-in-out duration-200 font-semibold;
&.active,
&:hover {
From 7d24720ef7d5f39c58d5eadf02af8144c5348fe6 Mon Sep 17 00:00:00 2001
From: ItsLame <37344470+ItsLame@users.noreply.github.com>
Date: Mon, 9 Jun 2025 22:05:02 +1000
Subject: [PATCH 09/10] fix: build error
---
src/components/ProjectCard.tsx | 2 +-
src/models/common.types.d.ts | 4 ++--
src/models/mouse-tooltip.types.d.ts | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/components/ProjectCard.tsx b/src/components/ProjectCard.tsx
index 895aa30..195c00b 100644
--- a/src/components/ProjectCard.tsx
+++ b/src/components/ProjectCard.tsx
@@ -1,7 +1,7 @@
import { IconBrandYoutube, IconBrush, IconCode, IconExternalLink, IconFile, IconPlayerPlay } from "@tabler/icons-react";
import React, { ReactNode } from "react";
import Link from "next/link";
-import { IBaseChildrenProps, NullableString } from "@/models";
+import { IBaseChildrenProps, IMouseTooltipHandler, NullableString } from "@/models";
interface IProjectTagProps extends IBaseChildrenProps {}
diff --git a/src/models/common.types.d.ts b/src/models/common.types.d.ts
index 84ec575..ccf16f2 100644
--- a/src/models/common.types.d.ts
+++ b/src/models/common.types.d.ts
@@ -1,7 +1,7 @@
import { ReactElement, ReactNode } from "react";
-interface IBaseChildrenProps {
+export interface IBaseChildrenProps {
children?: ReactNode | ReactElement | string,
}
-type NullableString = string | null;
+export type NullableString = string | null;
diff --git a/src/models/mouse-tooltip.types.d.ts b/src/models/mouse-tooltip.types.d.ts
index 444fba1..c23b4ca 100644
--- a/src/models/mouse-tooltip.types.d.ts
+++ b/src/models/mouse-tooltip.types.d.ts
@@ -1,4 +1,4 @@
-interface IMouseTooltipHandler {
+export interface IMouseTooltipHandler {
updateText: (_text: string) => void,
updateVisibility: (_visibility: boolean) => void,
}
From 1f70ec391aec11d49fa52a0a6ad42009488c81c1 Mon Sep 17 00:00:00 2001
From: ItsLame <37344470+ItsLame@users.noreply.github.com>
Date: Mon, 9 Jun 2025 22:29:59 +1000
Subject: [PATCH 10/10] fix: build error
---
src/components/ProjectCards.tsx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/components/ProjectCards.tsx b/src/components/ProjectCards.tsx
index 9c18ae9..2a84669 100644
--- a/src/components/ProjectCards.tsx
+++ b/src/components/ProjectCards.tsx
@@ -4,6 +4,8 @@ import MouseTooltip from "@/components/MouseTooltip";
import React, { useState } from "react";
import ProjectCard from "@/components/ProjectCard";
import { PaginatedDocs } from "payload";
+import { IMouseTooltipHandler } from "@/models";
+
const ProjectCards = ({ projects }: { projects: PaginatedDocs }) => {
const [tooltipText, setTooltipText] = useState("i like kway teow");