Skip to content

Commit 354dbc6

Browse files
committed
feat: add work experience section and various UI components
1 parent 62759e9 commit 354dbc6

27 files changed

Lines changed: 768 additions & 856 deletions

app/global-error.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
"use client";
2+
3+
import ErrorReporter from "@/components/ErrorReporter";
4+
5+
export default ErrorReporter;

app/globals.css

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* Updated: 2025-10-31T07:17:43.259Z */
12
@tailwind base;
23
@tailwind components;
34
@tailwind utilities;
@@ -85,16 +86,22 @@
8586
}
8687

8788
::-webkit-scrollbar-track {
88-
background: rgba(15, 15, 15, 0.5);
89+
background: hsl(var(--muted) / 0.3);
90+
border-radius: 4px;
8991
}
9092

9193
::-webkit-scrollbar-thumb {
92-
background: rgba(139, 92, 246, 0.5);
94+
background: hsl(var(--muted-foreground) / 0.4);
9395
border-radius: 4px;
96+
transition: background 0.3s ease;
9497
}
9598

9699
::-webkit-scrollbar-thumb:hover {
97-
background: rgba(139, 92, 246, 0.8);
100+
background: hsl(var(--muted-foreground) / 0.6);
101+
}
102+
103+
::-webkit-scrollbar-corner {
104+
background: hsl(var(--muted) / 0.3);
98105
}
99106

100107
/* Gradient text */
@@ -104,7 +111,7 @@
104111

105112
/* Glassmorphism */
106113
.glass {
107-
@apply bg-gray-900/50 backdrop-blur-sm border border-gray-800;
114+
@apply bg-card/50 backdrop-blur-sm border border-border;
108115
}
109116

110117
/* Glow effects */
@@ -120,3 +127,8 @@
120127
.parallax {
121128
transition: transform 0.2s ease-out;
122129
}
130+
131+
/* Hide Next.js error overlay portal */
132+
nextjs-portal {
133+
display: none !important;
134+
}

app/layout.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { Metadata } from "next"
33
import { Inter } from "next/font/google"
44
import "./globals.css"
55
import { ThemeProvider } from "@/components/theme-provider"
6+
import ErrorReporter from "@/components/ErrorReporter";
67
import Script from "next/script";
78
import { Analytics } from "@vercel/analytics/next"
89

@@ -71,11 +72,22 @@ export const metadata: Metadata = {
7172
export default function RootLayout({
7273
children,
7374
}: Readonly<{
74-
children: React.ReactNode
75+
children: React.ReactNode;
7576
}>) {
7677
return (
77-
<html lang="en" className="dark" style={{ colorScheme: "dark" }}>
78-
<body className={inter.className}>
78+
<html lang="en">
79+
<body className="antialiased">
80+
<ErrorReporter />
81+
<Script
82+
src="https://slelguoygbfzlpylpxfs.supabase.co/storage/v1/object/public/scripts//route-messenger.js"
83+
strategy="afterInteractive"
84+
data-target-origin="*"
85+
data-message-type="ROUTE_CHANGE"
86+
data-include-search-params="true"
87+
data-only-in-iframe="true"
88+
data-debug="true"
89+
data-custom-data='{"appName": "YourApp", "version": "1.0.0", "greeting": "hi"}'
90+
/>
7991
<ThemeProvider attribute="class" defaultTheme="dark" enableSystem={false} disableTransitionOnChange>
8092
{children}
8193
<Script
@@ -88,5 +100,5 @@ export default function RootLayout({
88100
<Analytics />
89101
</body>
90102
</html>
91-
)
92-
}
103+
);
104+
}

app/page.tsx

Lines changed: 14 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,18 @@
22

33
import { useEffect, useRef } from "react"
44
import { motion, useScroll, useTransform } from "framer-motion"
5-
import Hero from "@/components/sections/hero"
6-
import About from "@/components/sections/about"
75
import Skills from "@/components/sections/skills"
86
import Projects from "@/components/sections/projects"
9-
import CPProfiles from "@/components/sections/cp-profiles"
10-
import Achievements from "@/components/sections/achievements"
117
import Contact from "@/components/sections/contact"
128
import Footer from "@/components/sections/footer"
13-
import { Button } from "@/components/ui/button"
14-
import { ArrowUp } from "lucide-react"
9+
// import { Button } from "@/components/ui/button"
10+
// import { ArrowUp } from "lucide-react"
1511
import Navbar from "@/components/sections/navbar"
12+
import Intro from "@/components/sections/intro"
13+
import WorkExperience from "@/components/sections/work-experience"
1614

1715
export default function Home() {
18-
const { scrollY } = useScroll()
19-
const scrollToTopRef = useRef<HTMLDivElement>(null)
20-
const opacity = useTransform(scrollY, [0, 200], [0, 1])
21-
22-
const scrollToTop = () => {
23-
window.scrollTo({ top: 0, behavior: "smooth" })
24-
}
25-
16+
2617
// Intersection Observer for animations
2718
useEffect(() => {
2819
const observer = new IntersectionObserver(
@@ -48,33 +39,22 @@ export default function Home() {
4839
}, [])
4940

5041
return (
51-
<main className="relative text-white min-h-screen">
52-
{/* Black Background */}
53-
<div className="fixed inset-0 bg-black/90 z-0"></div>
42+
<main className="relative min-h-screen">
43+
{/* Background */}
44+
<div className="fixed inset-0 bg-background z-0"></div>
5445

5546
{/* Content */}
5647
<div className="relative z-20">
5748
<Navbar />
58-
<Hero />
59-
<About />
49+
<Intro />
6050
<Skills />
6151
<Projects />
62-
<CPProfiles />
63-
<Achievements />
52+
<WorkExperience />
6453
<Contact />
65-
<Footer />
54+
<div className="hidden md:block">
55+
<Footer />
56+
</div>
6657
</div>
67-
68-
<motion.div ref={scrollToTopRef} style={{ opacity }} className="fixed bottom-8 right-8 z-50">
69-
<Button
70-
onClick={scrollToTop}
71-
size="icon"
72-
className="rounded-full bg-violet-700 hover:bg-violet-600 shadow-[0_0_15px_rgba(139,92,246,0.5)] transition-all duration-300 hover:shadow-[0_0_20px_rgba(139,92,246,0.8)]"
73-
>
74-
<ArrowUp className="h-5 w-5" />
75-
<span className="sr-only">Scroll to top</span>
76-
</Button>
77-
</motion.div>
7858
</main>
7959
)
80-
}
60+
}

components/ErrorReporter.tsx

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
"use client";
2+
3+
import { useEffect, useRef } from "react";
4+
5+
type ReporterProps = {
6+
/* ⎯⎯ props are only provided on the global-error page ⎯⎯ */
7+
error?: Error & { digest?: string };
8+
reset?: () => void;
9+
};
10+
11+
export default function ErrorReporter({ error, reset }: ReporterProps) {
12+
/* ─ instrumentation shared by every route ─ */
13+
const lastOverlayMsg = useRef("");
14+
const pollRef = useRef<NodeJS.Timeout>(setInterval(() => {}, 2000));
15+
16+
useEffect(() => {
17+
const inIframe = window.parent !== window;
18+
if (!inIframe) return;
19+
20+
const send = (payload: unknown) => window.parent.postMessage(payload, "*");
21+
22+
const onError = (e: ErrorEvent) =>
23+
send({
24+
type: "ERROR_CAPTURED",
25+
error: {
26+
message: e.message,
27+
stack: e.error?.stack,
28+
filename: e.filename,
29+
lineno: e.lineno,
30+
colno: e.colno,
31+
source: "window.onerror",
32+
},
33+
timestamp: Date.now(),
34+
});
35+
36+
const onReject = (e: PromiseRejectionEvent) =>
37+
send({
38+
type: "ERROR_CAPTURED",
39+
error: {
40+
message: e.reason?.message ?? String(e.reason),
41+
stack: e.reason?.stack,
42+
source: "unhandledrejection",
43+
},
44+
timestamp: Date.now(),
45+
});
46+
47+
const pollOverlay = () => {
48+
const overlay = document.querySelector("[data-nextjs-dialog-overlay]");
49+
const node =
50+
overlay?.querySelector(
51+
"h1, h2, .error-message, [data-nextjs-dialog-body]"
52+
) ?? null;
53+
const txt = node?.textContent ?? node?.innerHTML ?? "";
54+
if (txt && txt !== lastOverlayMsg.current) {
55+
lastOverlayMsg.current = txt;
56+
send({
57+
type: "ERROR_CAPTURED",
58+
error: { message: txt, source: "nextjs-dev-overlay" },
59+
timestamp: Date.now(),
60+
});
61+
}
62+
};
63+
64+
window.addEventListener("error", onError);
65+
window.addEventListener("unhandledrejection", onReject);
66+
pollRef.current = setInterval(pollOverlay, 1000);
67+
68+
return () => {
69+
window.removeEventListener("error", onError);
70+
window.removeEventListener("unhandledrejection", onReject);
71+
pollRef.current && clearInterval(pollRef.current);
72+
};
73+
}, []);
74+
75+
/* ─ extra postMessage when on the global-error route ─ */
76+
useEffect(() => {
77+
if (!error) return;
78+
window.parent.postMessage(
79+
{
80+
type: "global-error-reset",
81+
error: {
82+
message: error.message,
83+
stack: error.stack,
84+
digest: error.digest,
85+
name: error.name,
86+
},
87+
timestamp: Date.now(),
88+
userAgent: navigator.userAgent,
89+
},
90+
"*"
91+
);
92+
}, [error]);
93+
94+
/* ─ ordinary pages render nothing ─ */
95+
if (!error) return null;
96+
97+
/* ─ global-error UI ─ */
98+
return (
99+
<html>
100+
<body className="min-h-screen bg-background text-foreground flex items-center justify-center p-4">
101+
<div className="max-w-md w-full text-center space-y-6">
102+
<div className="space-y-2">
103+
<h1 className="text-2xl font-bold text-destructive">
104+
Something went wrong!
105+
</h1>
106+
<p className="text-muted-foreground">
107+
An unexpected error occurred. Please try again fixing with Orchids
108+
</p>
109+
</div>
110+
<div className="space-y-2">
111+
{process.env.NODE_ENV === "development" && (
112+
<details className="mt-4 text-left">
113+
<summary className="cursor-pointer text-sm text-muted-foreground hover:text-foreground">
114+
Error details
115+
</summary>
116+
<pre className="mt-2 text-xs bg-muted p-2 rounded overflow-auto">
117+
{error.message}
118+
{error.stack && (
119+
<div className="mt-2 text-muted-foreground">
120+
{error.stack}
121+
</div>
122+
)}
123+
{error.digest && (
124+
<div className="mt-2 text-muted-foreground">
125+
Digest: {error.digest}
126+
</div>
127+
)}
128+
</pre>
129+
</details>
130+
)}
131+
</div>
132+
</div>
133+
</body>
134+
</html>
135+
);
136+
}

0 commit comments

Comments
 (0)