feat: create landing page [TASK 2] [ARCHIVED]#19
feat: create landing page [TASK 2] [ARCHIVED]#19burgerphilic18 wants to merge 8 commits intop-society:mainfrom
Conversation
Signed-off-by: Spandan Hota <spandanhota2005@outlook.com>
Signed-off-by: Spandan Hota <spandanhota2005@outlook.com>
There was a problem hiding this comment.
Summary of Changes
Hello @burgerphilic18, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request significantly overhauls the application's entry point by introducing a new, feature-rich landing page. The primary goal is to provide an engaging and informative experience for unauthenticated users, guiding them towards registration or login. The changes encompass a complete redesign of the home page, a revamped header with responsive navigation, and the establishment of a consistent pixel-art visual theme across these new elements.
Highlights
- New Landing Page: Introduced a comprehensive landing page for unauthenticated users, serving as the new root (
_index.tsx) of the application. This page provides an overview of the IIITBuzz platform, its features, and prominent calls to action for signing up or logging in. - Responsive Navigation: Implemented a responsive navigation system, featuring a new mobile-specific drawer accessible via a hamburger menu in the header, and a dedicated desktop sidebar. Both utilize a new
SidebarItemcomponent for consistent navigation links. - Pixel-Art Aesthetic & Theming: Adopted a distinct pixel-art visual style across the landing page, including custom fonts, pixelated shadows, and a dynamic theme palette (
useThemePalette) that adjusts colors for light and dark modes. - User Engagement Features: The landing page now includes a 'Welcome to IIITBuzz' section highlighting key features with custom
Badgecomponents, and a dynamic section displaying a random post to showcase community activity, complete withPostButtoncomponents for interaction.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Code Review
This pull request successfully implements a new landing page with a responsive design. The code is well-structured for the most part, but there are some critical areas for improvement. The main concerns are the custom theming implementation, which conflicts with the existing ThemeProvider, and the duplication/local definition of several components. Addressing these will significantly improve the maintainability and robustness of the codebase. I've left detailed comments on these points.
apps/web/src/routes/_index.tsx
Outdated
| function useThemePalette() { | ||
| useEffect(() => { | ||
| function setPalette(theme: "light" | "dark") { | ||
| const root = document.documentElement; | ||
| if (theme === "dark") { | ||
| root.style.setProperty("--bg", "#141420"); | ||
| root.style.setProperty("--surface", "#1c1c2a"); | ||
| root.style.setProperty("--primary", "#62d8e2"); | ||
| root.style.setProperty("--accent", "#e870a7"); | ||
| root.style.setProperty("--secondary", "#f18e5d"); | ||
| root.style.setProperty("--badge", "#bca4e2"); | ||
| root.style.setProperty("--border", "#3c3c4a"); | ||
| root.style.setProperty("--text-primary", "#f5f5f5"); | ||
| root.style.setProperty("--text-secondary", "#aaaaaa"); | ||
| } else { | ||
| root.style.setProperty("--bg", "#fce9d6"); | ||
| root.style.setProperty("--surface", "#fffdfb"); | ||
| root.style.setProperty("--primary", "#62d8e2"); | ||
| root.style.setProperty("--accent", "#f4be52"); | ||
| root.style.setProperty("--secondary", "#f18e5d"); | ||
| root.style.setProperty("--badge", "#f8b3c8"); | ||
| root.style.setProperty("--border", "#888888"); | ||
| root.style.setProperty("--text-primary", "#2d2d2d"); | ||
| root.style.setProperty("--text-secondary", "#5a5a5a"); | ||
| } | ||
| } | ||
|
|
||
| const isDark = window.matchMedia("(prefers-color-scheme: dark)").matches; | ||
| setPalette(isDark ? "dark" : "light"); | ||
| const observer = new MutationObserver(() => { | ||
| const html = document.documentElement; | ||
| if (html.classList.contains("dark")) setPalette("dark"); | ||
| else setPalette("light"); | ||
| }); | ||
| observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"] }); | ||
|
|
||
| return () => observer.disconnect(); | ||
| }, []); | ||
| } |
There was a problem hiding this comment.
This custom hook manually manages theme variables by directly manipulating the DOM and using a MutationObserver. This is an anti-pattern in React and conflicts with the existing ThemeProvider and Tailwind CSS setup. The ThemeProvider is already configured to toggle a dark class on the <html> element.
The correct approach is to define your theme variables within your global CSS file (index.css) under :root and .dark selectors. This simplifies the logic, removes the need for this hook and the MutationObserver, and properly leverages the tools you're already using.
apps/web/src/routes/_index.tsx
Outdated
| </div> | ||
| </div> | ||
| ); | ||
| useThemePalette(); |
apps/web/src/routes/_index.tsx
Outdated
| <a href="/signup" aria-label="Sign up for IIITBuzz"> | ||
| <button | ||
| className="px-5 py-2 rounded border-2 font-bold pixel-font shadow-pixel transition-all duration-150 w-full sm:w-auto" | ||
| style={{ | ||
| background: "var(--primary)", | ||
| color: "var(--bg)", | ||
| borderColor: "var(--primary)", | ||
| }} | ||
| > | ||
| Sign Up | ||
| </button> | ||
| </a> |
There was a problem hiding this comment.
Placing a <button> element inside an <a> tag is not valid HTML and can cause accessibility issues. For navigation, an <a> tag should be used directly. You can apply the button styling directly to the <a> tag.
This also applies to the "Log In" button below.
<a
href="/signup"
aria-label="Sign up for IIITBuzz"
className="px-5 py-2 rounded border-2 font-bold pixel-font shadow-pixel transition-all duration-150 w-full sm:w-auto"
style={{
background: "var(--primary)",
color: "var(--bg)",
borderColor: "var(--primary)",
}}
>
Sign Up
</a>
apps/web/src/routes/_index.tsx
Outdated
| function SidebarItem({ icon, label, active = false }: { icon: string; label: string; active?: boolean }) { | ||
| return ( | ||
| <div | ||
| className={`flex items-center gap-3 px-3 py-2 rounded font-bold pixel-font text-sm cursor-pointer w-full | ||
| ${active ? "border-l-4" : "hover:bg-[var(--bg)]"} | ||
| `} | ||
| style={{ | ||
| background: active ? "var(--bg)" : "transparent", | ||
| color: active ? "var(--primary)" : "var(--text-secondary)", | ||
| borderColor: active ? "var(--primary)" : undefined, | ||
| }} | ||
| title={label} | ||
| > | ||
| <span className="text-lg flex-shrink-0">{icon}</span> | ||
| <span className="break-words">{label}</span> | ||
| </div> | ||
| ); | ||
| } | ||
|
|
||
| const Badge: React.FC<{ children: React.ReactNode }> = ({ children }) => { | ||
| return ( | ||
| <span | ||
| className="px-3 py-1 rounded font-bold pixel-font text-xs border-2 break-words" | ||
| style={{ | ||
| background: "var(--border)", | ||
| color: "var(--badge)", | ||
| borderColor: "var(--badge)", | ||
| }} | ||
| > | ||
| {children} | ||
| </span> | ||
| ); | ||
| }; | ||
|
|
||
| const PostButton: React.FC<{ children: React.ReactNode }> = ({ children }) => { | ||
| return ( | ||
| <button | ||
| className="px-2 py-1 rounded border-2 pixel-font text-xs transition-all duration-150 break-words" | ||
| style={{ | ||
| background: "var(--bg)", | ||
| color: "var(--badge)", | ||
| borderColor: "var(--border)", | ||
| }} | ||
| > | ||
| {children} | ||
| </button> | ||
| ); | ||
| }; No newline at end of file |
There was a problem hiding this comment.
The SidebarItem, Badge, and PostButton components are defined locally within this route file. This has a couple of issues:
- Code Duplication:
SidebarItemis also defined insrc/components/sidebar-item.tsx, which is a significant maintainability problem. - Separation of Concerns: Reusable presentational components like these should live in the
src/componentsdirectory to be easily imported and used across the application.
Please remove these local definitions. Import SidebarItem from its existing file, and move Badge and PostButton to new files in the components directory.
There was a problem hiding this comment.
wrote everything in index.tsx first then moved it into sidebar.tsx then forgot to delete this from index.tsx . will move it in next commit
apps/web/src/components/header.tsx
Outdated
| <SidebarItem icon="🏠" label="Home" active /> | ||
| <SidebarItem icon="🗂️" label="Categories" /> | ||
| <SidebarItem icon="🏷️" label="Tags" /> | ||
| <SidebarItem icon="📢" label="Announcements" /> | ||
| <SidebarItem icon="🏆" label="Leaderboard" /> | ||
| <SidebarItem icon="ℹ️" label="About" /> |
There was a problem hiding this comment.
The navigation links in the mobile drawer are hardcoded. This is less maintainable than defining them as a data structure (like an array of objects) and rendering them with .map(). This approach makes it much easier to add, remove, or reorder navigation items in the future.
For example:
const navItems = [
{ icon: "🏠", label: "Home", active: true },
{ icon: "🗂️", label: "Categories" },
{ icon: "🏷️", label: "Tags" },
{ icon: "📢", label: "Announcements" },
{ icon: "🏆", label: "Leaderboard" },
{ icon: "ℹ️", label: "About" },
];
// ... inside the component's return
<nav className="flex flex-col gap-2 p-4" aria-label="Mobile Navigation">
{navItems.map(item => <SidebarItem key={item.label} {...item} />)}
</nav>| @@ -0,0 +1,18 @@ | |||
| export default function SidebarItem({ icon, label, active = false }: { icon: string; label: string; active?: boolean }) { | |||
There was a problem hiding this comment.
The component's props are typed inline. For better readability and to adhere to common React/TypeScript best practices, it's better to define a separate type or interface for the props.
Example:
type SidebarItemProps = {
icon: string;
label: string;
active?: boolean;
};
export default function SidebarItem({ icon, label, active = false }: SidebarItemProps) { /* ... */ }
apps/web/src/routes/_index.tsx
Outdated
| import { ThemeProvider } from "@/components/theme-provider"; | ||
| import { Menu, X } from "lucide-react"; // Lucide icons for hamburger |
apps/web/src/routes/_index.tsx
Outdated
| </div> | ||
| ); | ||
| useThemePalette(); | ||
| const [isMobileMenuOpen, setMobileMenuOpen] = useState(false); |
apps/web/src/routes/_index.tsx
Outdated
| <style> | ||
| {` | ||
| @import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap'); | ||
| .pixel-font { font-family: 'Press Start 2P', monospace !important; } | ||
| .shadow-pixel { box-shadow: 4px 4px 0 var(--border), 8px 8px 0 var(--bg); } | ||
| .drop-shadow-pixel { text-shadow: 2px 2px 0 var(--border), 4px 4px 0 var(--bg); } | ||
| `} | ||
| </style> |
There was a problem hiding this comment.
Using an inline <style> tag for global styles is not ideal for maintainability. These styles should be moved to a dedicated CSS file.
- The font import (
@import url(...)) should be moved toapps/web/src/index.css. - The utility classes (
.pixel-font,.shadow-pixel, etc.) should also be moved toapps/web/src/index.css, preferably within a@layer utilitiesblock to integrate them with Tailwind CSS.
|
@burgerphilic18 always take a fetch from upstream before raising a pull-request |
Signed-off-by: Spandan Hota <spandanhota2005@outlook.com>
|
@burgerphilic18 check wheather lefthook is working or not now ? |
|
@burgerphilic18 also ran |
|
Signed-off-by: Spandan Hota <spandanhota2005@outlook.com>
…into landing-page
this came first time or comes everytime u commit from starting ? |
everytime I commit from starting of this PR |
run pnpm install once tell me wheather its working or not |
working now |
|
uf this looks so good! Lemme review. Apologies for the delay in the review. |
Signed-off-by: Spandan Hota <spandanhota2005@outlook.com>
|
Hey @burgerphilic18 ! Although this layout fulfills all mentioned requirements of the landing page, this isn't a proper layout of landing page per se. That said, this looks good and I thinking clubbing this with #20 will make a good pairing. So here's the to-do for you-I'd recommend you to keep this PR intact, rebase to main once we merge #20 to main. Then we can convert this PR to a dark mode extended version of the same. What say? @burgerphilic18 @iamanishx @neoandmatrix @consoledotaman |
Totally agree. |
I took inspiration from xda and reddit's landing page to create this design. In that case, we can take Aman's landing page then use this layout for forum main ui after login. sidebar header card and badges components can be reused again that I made in this PR? |
You spoke exactly what was on my mind. So I guess your work rn is to replicate a landing page with the color scheme you already have, with the layout of what Aman has made. |
|
@burgerphilic18 now that #20 has been merged, we want you to create another PR(or if you can, rebase this branch to the new merged main) that will only implement your dark mode colorscheme to the landing page already merged. This will replace that yellow-bg (not the white one) ugly looking theme and hence the final output will be If possible, do not delete this branch, we want to use the components made here such as sidebar etc. later on when we will work on the main forum itself. Can you do it? Thank you for your patience |
just a short note to help-
|
creating a new pr with required dark mode theme edit: #21 raised |




Summary
This PR creates a landing page for unauthorised users with prominent login and signup buttons
Checklist
Screenshot
Desktop

Mobile


fixes #5
Will make further commits after reviews from gemini bot and other maintainers