Skip to content

Commit 38d1592

Browse files
committed
feat(frontend): implement authors and resources pages with metadata and layout components
1 parent 97c68fb commit 38d1592

File tree

13 files changed

+686
-6
lines changed

13 files changed

+686
-6
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { Metadata } from "next";
2+
import { PROJECT_NAME } from "@/config/constants";
3+
4+
export const metadata: Metadata = {
5+
title: `Authors - ${PROJECT_NAME}`,
6+
description: "Authors page",
7+
};
8+
9+
export default function AuthorsPage() {
10+
return (
11+
<main className="max-w-screen-xl mx-auto p-4">
12+
<h1>Authors</h1>
13+
</main>
14+
);
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { Metadata } from "next";
2+
import { PROJECT_NAME } from "@/config/constants";
3+
4+
export const metadata: Metadata = {
5+
title: `Resources - ${PROJECT_NAME}`,
6+
description: "Resources page",
7+
};
8+
9+
export default function ResourcesPage() {
10+
return (
11+
<main className="max-w-screen-xl mx-auto p-4">
12+
<h1>ResourcesPage</h1>
13+
</main>
14+
);
15+
}

frontend/src/app/layout.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Metadata } from "next";
22
import { Outfit, Roboto_Mono } from "next/font/google";
33
import { PROJECT_NAME, PROJECT_DESCRIPTION } from "@/config/constants";
4-
// import { Footer, Navigation } from "@/components/layout";
4+
import { Footer, Navigation } from "@/components/layout";
55
import Providers from "./providers";
66
import "../styles/globals.css";
77

@@ -31,9 +31,9 @@ export default function RootLayout({ children }: Props) {
3131
<body className={`${outfit.variable} ${robotoMono.variable} antialiased`}>
3232
<Providers>
3333
<div className="min-h-screen flex flex-col">
34-
{/* <Navigation /> */}
34+
<Navigation />
3535
{children}
36-
{/* <Footer /> */}
36+
<Footer />
3737
</div>
3838
</Providers>
3939
</body>

frontend/src/app/page.tsx

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,47 @@
1+
"use client";
2+
3+
import { Button } from "@heroui/react";
4+
import { Filter } from "lucide-react";
5+
import { HeroSection } from "@/components/home";
6+
import { ResourceCard } from "@/components/resources";
7+
8+
import resources from "@/data/resources.json";
9+
110
export default function HomePage() {
211
return (
3-
<div className="h-screen w-fulll bg-red-500 flex justify-center items-center">
4-
<h1 className="text-6xl">Code Atlas</h1>
5-
</div>
12+
<main className="min-h-screen bg-white">
13+
<HeroSection />
14+
15+
{/* Categories and Filters */}
16+
<section className="border-t border-gray-100 py-4">
17+
<div className="container mx-auto px-4 flex justify-between items-center">
18+
{/* <Tabs defaultValue="discover" className="w-auto">
19+
<TabsList className="bg-transparent h-auto p-0 gap-6">
20+
<TabsTrigger
21+
value="discover"
22+
className="data-[state=active]:bg-transparent data-[state=active]:shadow-none data-[state=active]:text-black data-[state=active]:font-medium px-0 py-2"
23+
>
24+
Discover
25+
</TabsTrigger>
26+
</TabsList>
27+
</Tabs> */}
28+
<Button variant="ghost" className="gap-2">
29+
<Filter className="h-4 w-4" />
30+
Filters
31+
</Button>
32+
</div>
33+
</section>
34+
35+
{/* Design Grid */}
36+
<section className="py-8">
37+
<div className="container mx-auto px-4">
38+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
39+
{resources.map((resource) => (
40+
<ResourceCard key={resource.id} resource={resource} />
41+
))}
42+
</div>
43+
</div>
44+
</section>
45+
</main>
646
);
747
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import {
2+
Button,
3+
Input,
4+
Chip,
5+
Dropdown,
6+
DropdownTrigger,
7+
DropdownMenu,
8+
DropdownItem,
9+
} from "@heroui/react";
10+
import { Search, ChevronDown } from "lucide-react";
11+
12+
const SearchBar = () => {
13+
return (
14+
<div className="max-w-2xl mx-auto mb-8">
15+
<Input
16+
type="text"
17+
size="lg"
18+
variant="bordered"
19+
placeholder="What are you looking for?"
20+
classNames={{
21+
inputWrapper: ["py-8", "px-6"],
22+
}}
23+
endContent={
24+
<div className="flex items-center gap-2">
25+
<Dropdown>
26+
<DropdownTrigger>
27+
<Button
28+
variant="bordered"
29+
endContent={<ChevronDown size={20} />}
30+
>
31+
Shots
32+
</Button>
33+
</DropdownTrigger>
34+
<DropdownMenu aria-label="Search by category">
35+
<DropdownItem key="resources">Resources</DropdownItem>
36+
<DropdownItem key="authors">Authors</DropdownItem>
37+
</DropdownMenu>
38+
</Dropdown>
39+
<Button isIconOnly size="sm" className="bg-black">
40+
<Search className="h-4 w-4 text-white" />
41+
</Button>
42+
</div>
43+
}
44+
/>
45+
</div>
46+
);
47+
};
48+
49+
const HeroSection = () => {
50+
return (
51+
<section className="py-16 text-center">
52+
<div className="container mx-auto px-4">
53+
<h1 className="text-4xl md:text-6xl font-bold mb-4 max-w-xl mx-auto">
54+
Resources made by devs, for devs
55+
</h1>
56+
<p className="text-neutral-500 max-w-2xl mx-auto mb-10">
57+
Everything you need to build, learn, and level up — all in one place.
58+
</p>
59+
<SearchBar />
60+
61+
{/* Trending Tags */}
62+
<div className="flex flex-wrap justify-center gap-2 mb-12">
63+
<span className="text-gray-500 mr-2">Trending searches</span>
64+
<Chip>landing page</Chip>
65+
<Chip>e-commerce</Chip>
66+
<Chip>mobile app</Chip>
67+
<Chip>logo design</Chip>
68+
<Chip>dashboard</Chip>
69+
<Chip>icons</Chip>
70+
</div>
71+
</div>
72+
</section>
73+
);
74+
};
75+
76+
export default HeroSection;

frontend/src/components/home/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as HeroSection } from "./hero-section";
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"use client";
2+
3+
import Link from "next/link";
4+
import { FOOTER_LINKS, PROJECT_NAME } from "@/config/constants";
5+
import { usePathname } from "next/navigation";
6+
7+
export default function Footer() {
8+
const pathname = usePathname();
9+
const ignoredRoutes = ["/dashboard", "/auth/google", "/auth/facebook"];
10+
const isIgnoredRoute = ignoredRoutes.some((route) =>
11+
pathname.startsWith(route),
12+
);
13+
if (isIgnoredRoute) return null;
14+
15+
return (
16+
<footer className="mt-auto py-8 border-t border-t-neutral-300">
17+
<div className="max-w-screen-xl mx-auto px-6 space-y-4">
18+
<div className="flex justify-center">
19+
<div className="flex space-x-6">
20+
{FOOTER_LINKS.map((link) => (
21+
<Link
22+
key={link.href}
23+
href={link.href}
24+
className="hover:text-primary hover:underline"
25+
>
26+
{link.name}
27+
</Link>
28+
))}
29+
</div>
30+
</div>
31+
<div className="text-center">
32+
<p>
33+
&copy; {new Date().getFullYear()} {`${PROJECT_NAME}`} - All rights
34+
reserved.
35+
</p>
36+
</div>
37+
</div>
38+
</footer>
39+
);
40+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { default as Navigation } from "./navigation";
2+
export { default as Footer } from "./footer";

0 commit comments

Comments
 (0)