Skip to content

Commit 9c1fe5f

Browse files
committed
Add remainder od chrome and content on home page
1 parent 6ce9998 commit 9c1fe5f

File tree

13 files changed

+383
-10
lines changed

13 files changed

+383
-10
lines changed

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
"dependencies": {
2424
"@auth/prisma-adapter": "^2.7.2",
2525
"@prisma/client": "^5.14.0",
26+
"@radix-ui/react-icons": "^1.3.1",
27+
"@radix-ui/react-slot": "^1.1.0",
2628
"@t3-oss/env-nextjs": "^0.10.1",
2729
"@tanstack/react-query": "^5.50.0",
2830
"@trpc/client": "^11.0.0-rc.446",
@@ -32,6 +34,7 @@
3234
"clsx": "^2.1.1",
3335
"framer-motion": "^11.11.11",
3436
"geist": "^1.3.0",
37+
"hugeicons-react": "^0.3.0",
3538
"lucide-react": "^0.456.0",
3639
"next": "^15.0.1",
3740
"next-auth": "5.0.0-beta.25",

public/bento/clackr.png

709 KB
Loading

public/bento/hyprmac.png

149 KB
Loading

public/bento/reearth.png

2.55 MB
Loading

public/favicon.ico

230 KB
Binary file not shown.

src/app/_components/navbar.tsx

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
"use client";
2+
3+
import { GithubIcon, Linkedin01Icon, TwitterIcon } from "hugeicons-react";
4+
import Link from "next/link";
5+
import BlurFade from "~/components/ui/blur-fade";
6+
import { Button } from "~/components/ui/button";
7+
8+
export const Navbar = () => {
9+
const links = [
10+
{ name: "Home", href: "/" },
11+
{ name: "About", href: "/about" },
12+
{ name: "Contact", href: "/contact" },
13+
{ name: "Blog", href: "/blog" },
14+
];
15+
const externalLinks = [
16+
{ Icon: <GithubIcon />, href: "https://github.com/hackrmomo" },
17+
{ Icon: <Linkedin01Icon />, href: "https://www.linkedin.com/in/mohammadalahdal/" },
18+
{ Icon: <TwitterIcon />, href: "https://twitter.com/0xh4ckr" },
19+
];
20+
return <>
21+
<nav className="fixed top-0 left-0 right-0 z-50">
22+
<div className="relative flex flex-row items-center justify-between p-4 gradient-blur backdrop-blur-lg pb-20">
23+
<div className="flex flex-row items-center gap-4">
24+
{links.map((link, i) => (
25+
<BlurFade key={link.name} delay={1 + i * 0.15}>
26+
<Button variant="ghost" asChild key={link.name}>
27+
<Link href={link.href}>
28+
{link.name}
29+
</Link>
30+
</Button>
31+
</BlurFade>
32+
))}
33+
</div>
34+
<div className="flex flex-row items-center gap-4">
35+
{externalLinks.map((link, i) => (
36+
<BlurFade key={link.href} delay={1.6 + i * 0.15}>
37+
<Button variant="ghost" asChild key={link.href}>
38+
<Link href={link.href}>
39+
{link.Icon}
40+
</Link>
41+
</Button>
42+
</BlurFade>
43+
))}
44+
</div>
45+
{/* <div className="absolute top-0 left-0 right-0 h-full gradient-blur backdrop-blur-lg" /> */}
46+
</div>
47+
</nav>
48+
</>
49+
};

src/app/layout.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import "~/styles/globals.css";
22
import "~/styles/fonts.css";
3+
import "~/styles/fx.css";
34

45
import { GeistSans } from "geist/font/sans";
56
import { type Metadata } from "next";
67

78
import { TRPCReactProvider } from "~/trpc/react";
9+
import { Navbar } from "./_components/navbar";
810

911
export const metadata: Metadata = {
1012
title: "Mohammad Al-Ahdal",
@@ -16,8 +18,9 @@ export default function RootLayout({
1618
children,
1719
}: Readonly<{ children: React.ReactNode }>) {
1820
return (
19-
<html lang="en" className={`${GeistSans.variable}`}>
20-
<body className="bg-[#0A2239] flex flex-row items-center justify-center">
21+
<html lang="en" className={`${GeistSans.variable} dark`}>
22+
<body className="bg-[#0A2239] flex flex-column items-center justify-center">
23+
<Navbar />
2124
<TRPCReactProvider>{children}</TRPCReactProvider>
2225
</body>
2326
</html>

src/app/page.tsx

Lines changed: 84 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
import Image from "next/image";
21
import BlurFade from "~/components/ui/blur-fade";
32
import BlurIn from "~/components/ui/blur-in";
43
import HyperText from "~/components/ui/hyper-text";
54
import { auth } from "~/server/auth";
65
import { api, HydrateClient } from "~/trpc/server";
76
import { ProfilePicture } from "./_components/pfp";
7+
import GridPattern from "~/components/ui/grid-pattern";
8+
import { cn } from "~/lib/utils";
9+
import { BentoCard, BentoGrid } from "~/components/ui/bento-grid";
10+
import { DashboardSquare03Icon, GameController03Icon, KeyboardIcon } from "hugeicons-react"
11+
import { StackIcon } from "@radix-ui/react-icons";
12+
import Image from "next/image";
813

914
export default async function Home() {
1015
const session = await auth();
@@ -13,6 +18,49 @@ export default async function Home() {
1318
void api.blogPost.getLatest.prefetch();
1419
}
1520

21+
const bentoLinks = [
22+
{
23+
Icon: DashboardSquare03Icon,
24+
name: "HyprMac",
25+
href: "https://github.com/hackrmomo/hyprmac",
26+
cta: "GitHub",
27+
background: <>
28+
<Image src={"/bento/hyprmac.png"} alt="HyprMac" fill objectFit="cover" />
29+
</>,
30+
className: "lg:row-start-1 lg:row-end-2 lg:col-start-1 lg:col-end-3",
31+
},
32+
{
33+
Icon: KeyboardIcon,
34+
name: "Clackr",
35+
href: "https://github.com/hackrmomo/clackr",
36+
cta: "GitHub",
37+
background: <>
38+
<Image src={"/bento/clackr.png"} alt="Clackr" fill objectFit="cover" />
39+
</>,
40+
className: "lg:row-start-1 lg:row-end-2 lg:col-start-3 lg:col-end-4",
41+
},
42+
{
43+
Icon: GameController03Icon,
44+
name: "ReEarth",
45+
href: "/blog/reearth",
46+
cta: "Read Blog Post",
47+
background: <>
48+
<Image src={"/bento/reearth.png"} alt="ReEarth" fill objectFit="cover" />
49+
</>,
50+
className: "lg:row-start-2 lg:row-end-3 lg:col-start-2 lg:col-end-4",
51+
},
52+
{
53+
Icon: StackIcon,
54+
name: "StackyBar",
55+
href: "https://github.com/hackrmomo/stackybar",
56+
cta: "GitHub",
57+
background: <>
58+
<GridPattern />
59+
</>,
60+
className: "lg:row-start-2 lg:row-end-3 lg:col-start-1 lg:col-end-2",
61+
},
62+
];
63+
1664
return (
1765
<HydrateClient>
1866
<main className="
@@ -29,7 +77,12 @@ export default async function Home() {
2977
justify-center
3078
items-center
3179
p-4
80+
py-40
3281
">
82+
<GridPattern
83+
strokeDasharray="4 2"
84+
className={cn("[mask-image:radial-gradient(60vw_circle_at_center,white,transparent)]") + " fixed"}
85+
/>
3386
<div className="flex flex-row items-center justify-center gap-4">
3487
<BlurFade>
3588
<ProfilePicture />
@@ -47,17 +100,40 @@ export default async function Home() {
47100
text-slate-400
48101
text-xs md:text-sm lg:text-base
49102
"
50-
text={`I'm a software engineer with ${Math.floor((Date.now() - 1514764800000) / 1000 / 60 / 60 / 24 / 365.25)} years of experience in the field.`}
103+
text={`I'm a software engineer with ${Math.floor((Date.now() - 1514764800000) / 1000 / 60 / 60 / 24 / 365.25)} years of experience, primarily in the fields of web and mobile development.`}
104+
/>
105+
</BlurFade>
106+
<BlurFade delay={0.6}>
107+
<HyperText
108+
className="
109+
text-slate-400
110+
text-xs md:text-sm lg:text-base
111+
"
112+
text="Here's a couple of things I'm currently working on:"
51113
/>
52114
</BlurFade>
53-
{/* Construction Sign */}
54-
<BlurIn className="flex flex-row items-center gap-2 absolute bottom-0 left-0 p-4 w-screen justify-center" delay={3} duration={0.3}>
55-
<span className="text-xs">🚧</span>
56-
<span className="text-base font-mono">please mind the scaffolding, the website is still under construction</span>
57-
<span className="text-xs">🚧</span>
58-
</BlurIn>
59115
</div>
60116
</div>
117+
<BentoGrid className="mt-8">
118+
{bentoLinks.map((bento, i) => (
119+
<BentoCard
120+
key={bento.name}
121+
href={bento.href}
122+
Icon={bento.Icon}
123+
name={bento.name}
124+
background={bento.background}
125+
cta={bento.cta}
126+
className={bento.className}
127+
delay={0.9 + i * 0.15}
128+
/>
129+
))}
130+
</BentoGrid>
131+
{/* Construction Sign */}
132+
<BlurIn className="flex flex-row items-center gap-2 fixed bottom-0 left-0 p-4 w-screen justify-center" delay={3} duration={0.3}>
133+
<span className="text-xs">🚧</span>
134+
<span className="text-base font-mono">please mind the scaffolding, the website is still under construction</span>
135+
<span className="text-xs">🚧</span>
136+
</BlurIn>
61137
</main>
62138
</HydrateClient>
63139
);

src/components/ui/bento-grid.tsx

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { ReactNode } from "react";
2+
import { ArrowRightIcon } from "@radix-ui/react-icons";
3+
4+
import { cn } from "~/lib/utils";
5+
import { Button } from "~/components/ui/button";
6+
import BlurFade from "./blur-fade";
7+
8+
const BentoGrid = ({
9+
children,
10+
className,
11+
}: {
12+
children: ReactNode;
13+
className?: string;
14+
}) => {
15+
return (
16+
<div
17+
className={cn(
18+
"grid w-full auto-rows-[22rem] grid-cols-3 gap-4",
19+
className,
20+
)}
21+
>
22+
{children}
23+
</div>
24+
);
25+
};
26+
27+
const BentoCard = ({
28+
name,
29+
className,
30+
background,
31+
Icon,
32+
description,
33+
href,
34+
cta,
35+
delay = 0,
36+
}: {
37+
name: string;
38+
className?: string;
39+
background?: ReactNode;
40+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
41+
Icon?: any
42+
description?: string;
43+
href?: string;
44+
cta?: string;
45+
delay?: number;
46+
}) => (
47+
<BlurFade
48+
delay={delay}
49+
key={name}
50+
className={cn(
51+
"group relative col-span-3 flex flex-col justify-between overflow-hidden rounded-xl",
52+
// light styles
53+
"bg-white [box-shadow:0_0_0_1px_rgba(0,0,0,.03),0_2px_4px_rgba(0,0,0,.05),0_12px_24px_rgba(0,0,0,.05)]",
54+
// dark styles
55+
"transform-gpu dark:bg-black dark:[border:1px_solid_rgba(255,255,255,.1)] dark:[box-shadow:0_-20px_80px_-20px_#ffffff1f_inset]",
56+
className,
57+
)}
58+
>
59+
<div className="absolute w-full h-[352px] filter brightness-50 saturate-50 blur-sm transition-all hover:blur-0 scale-150">{background}</div>
60+
<span></span>
61+
<div className="pointer-events-none z-10 flex transform-gpu flex-col gap-1 p-6 transition-all duration-300 group-hover:-translate-y-10">
62+
{Icon && <Icon className="h-12 w-12 origin-left transform-gpu text-neutral-200 transition-all duration-300 ease-in-out group-hover:scale-75" /> }
63+
<h3 className="text-xl font-semibold text-neutral-700 dark:text-neutral-300">
64+
{name}
65+
</h3>
66+
<p className="max-w-lg text-neutral-400">{description}</p>
67+
</div>
68+
69+
<div
70+
className={cn(
71+
"pointer-events-none absolute bottom-0 flex w-full translate-y-10 transform-gpu flex-row items-center p-4 opacity-0 transition-all duration-300 group-hover:translate-y-0 group-hover:opacity-100",
72+
)}
73+
>
74+
<Button variant="ghost" asChild size="sm" className="pointer-events-auto">
75+
<a href={href}>
76+
{cta}
77+
<ArrowRightIcon className="ml-2 h-4 w-4" />
78+
</a>
79+
</Button>
80+
</div>
81+
<div className="pointer-events-none absolute inset-0 transform-gpu transition-all duration-300 group-hover:bg-black/[.03] group-hover:dark:bg-neutral-800/10" />
82+
</BlurFade>
83+
);
84+
85+
export { BentoCard, BentoGrid };

src/components/ui/button.tsx

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import * as React from "react"
2+
import { Slot } from "@radix-ui/react-slot"
3+
import { cva, type VariantProps } from "class-variance-authority"
4+
5+
import { cn } from "~/lib/utils"
6+
7+
const buttonVariants = cva(
8+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
9+
{
10+
variants: {
11+
variant: {
12+
default:
13+
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
14+
destructive:
15+
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
16+
outline:
17+
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
18+
secondary:
19+
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
20+
ghost: "hover:bg-accent hover:text-accent-foreground",
21+
link: "text-primary underline-offset-4 hover:underline",
22+
},
23+
size: {
24+
default: "h-9 px-4 py-2",
25+
sm: "h-8 rounded-md px-3 text-xs",
26+
lg: "h-10 rounded-md px-8",
27+
icon: "h-9 w-9",
28+
},
29+
},
30+
defaultVariants: {
31+
variant: "default",
32+
size: "default",
33+
},
34+
}
35+
)
36+
37+
export interface ButtonProps
38+
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
39+
VariantProps<typeof buttonVariants> {
40+
asChild?: boolean
41+
}
42+
43+
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
44+
({ className, variant, size, asChild = false, ...props }, ref) => {
45+
const Comp = asChild ? Slot : "button"
46+
return (
47+
<Comp
48+
className={cn(buttonVariants({ variant, size, className }))}
49+
ref={ref}
50+
{...props}
51+
/>
52+
)
53+
}
54+
)
55+
Button.displayName = "Button"
56+
57+
export { Button, buttonVariants }

0 commit comments

Comments
 (0)