feat: create login page [TASK 3]#27
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 introduces a new, dedicated login page for the application, enabling users to sign in via their Google accounts. The page is designed to seamlessly integrate with the existing visual style, providing a consistent user experience while facilitating the authentication process.
Highlights
- New Login Page Component: A dedicated
LoginPagecomponent (apps/web/src/routes/login.tsx) has been introduced to handle user authentication. - Google Sign-in Integration: The login page includes a button that redirects users to
/auth/googleto initiate the Google sign-in flow. - Consistent UI/UX Design: The new login page adheres to the existing design language, incorporating 'neo-brutal' and 'ghibli-title' styles, along with animated visual elements and pixel patterns, as demonstrated in the provided screenshots.
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 introduces a new login page with Google authentication, which aligns with the existing design language. The implementation is solid. My review provides suggestions to enhance maintainability, accessibility, and adherence to common React best practices. Specifically, I've pointed out opportunities to handle hardcoded values, improve accessibility for an icon, and refactor repetitive code for better component structure.
| const redirectToGoogle = () => { | ||
| window.location.assign("/auth/google"); | ||
| }; |
There was a problem hiding this comment.
There are a couple of improvements that can be made here for better maintainability and adherence to React best practices:
- Avoid hardcoded URLs: The URL
/auth/googleis a "magic string". It's better to define this as a constant at the top of the file or in a shared constants file. This makes it easier to find and update all URL endpoints. - Function definition: The
redirectToGooglefunction is redefined on every render. Since it has no dependencies on component state or props, it can be defined outside the component scope to prevent unnecessary re-creations.
Here's an example of how you could refactor this:
// Defined outside the component
const GOOGLE_AUTH_URL = "/auth/google";
const redirectToGoogle = () => {
window.location.assign(GOOGLE_AUTH_URL);
};
export default function LoginPage() {
// ...
return (
// ...
<Button onClick={redirectToGoogle} ... />
// ...
);
}| <div className="absolute inset-0 overflow-hidden pointer-events-none z-10"> | ||
| <div | ||
| className="absolute top-10 left-10 w-2 h-2 bg-accent rounded-full animate-bounce" | ||
| style={{ animationDelay: "0s", animationDuration: "3s" }} | ||
| ></div> | ||
| <div | ||
| className="absolute top-20 right-20 w-1 h-1 bg-primary rounded-full animate-bounce" | ||
| style={{ animationDelay: "1s", animationDuration: "4s" }} | ||
| ></div> | ||
| <div | ||
| className="absolute top-40 left-1/4 w-1.5 h-1.5 bg-secondary rounded-full animate-bounce" | ||
| style={{ animationDelay: "2s", animationDuration: "5s" }} | ||
| ></div> | ||
| <div | ||
| className="absolute bottom-20 right-10 w-2 h-2 bg-accent rounded-full animate-bounce" | ||
| style={{ animationDelay: "0.5s", animationDuration: "3.5s" }} | ||
| ></div> | ||
| <div | ||
| className="absolute bottom-40 left-16 w-1 h-1 bg-primary rounded-full animate-bounce" | ||
| style={{ animationDelay: "1.5s", animationDuration: "4.5s" }} | ||
| ></div> | ||
| </div> | ||
|
|
||
| <div className="absolute inset-0 opacity-10 pixel-pattern z-10"></div> | ||
|
|
||
| <div className="container mx-auto px-4 text-center relative z-20"> | ||
| <div className="max-w-3xl mx-auto fade-in-up"> | ||
| <div className="flex justify-center mb-8 space-x-4"> | ||
| <div className="w-16 h-16 neo-brutal-card bg-green-200 border-green-500 flex items-center justify-center avatar-float"> | ||
| <img src="/images/avatar1.png" alt="Avatar1" /> | ||
| </div> | ||
| <div | ||
| className="w-16 h-16 neo-brutal-card bg-blue-200 border-blue-500 flex items-center justify-center avatar-float" | ||
| style={{ animationDelay: "0.5s" }} | ||
| > | ||
| <img src="/images/avatar2.png" alt="Avatar2" /> | ||
| </div> | ||
| <div | ||
| className="w-16 h-16 neo-brutal-card bg-yellow-200 border-yellow-500 flex items-center justify-center avatar-float" | ||
| style={{ animationDelay: "1s" }} | ||
| > | ||
| <img src="/images/avatar3.png" alt="Avatar3" /> | ||
| </div> | ||
| <div | ||
| className="w-16 h-16 neo-brutal-card bg-purple-200 border-purple-500 flex items-center justify-center avatar-float" | ||
| style={{ animationDelay: "1.5s" }} | ||
| > | ||
| <img src="/images/avatar4.png" alt="Avatar4" /> | ||
| </div> | ||
| </div> |
There was a problem hiding this comment.
The code for rendering decorative elements like the bouncing dots (lines 18-37) and the floating avatars (lines 44-66) is highly repetitive. To improve code clarity and maintainability, you could define the data for these elements in arrays and then use .map() to render them. This approach, known as being data-driven, makes the component's JSX cleaner and simplifies future modifications.
Example for Avatars:
const avatars = [
{ src: "/images/avatar1.png", alt: "Avatar1", className: "bg-green-200 border-green-500" },
{ src: "/images/avatar2.png", alt: "Avatar2", className: "bg-blue-200 border-blue-500", delay: "0.5s" },
// ... more avatars
];
// In your component's return statement:
<div className="flex justify-center mb-8 space-x-4">
{avatars.map((avatar, index) => (
<div
key={index}
className={`w-16 h-16 neo-brutal-card flex items-center justify-center avatar-float ${avatar.className}`}
style={{ animationDelay: avatar.delay }}
>
<img src={avatar.src} alt={avatar.alt} />
</div>
))}
</div>A similar approach can be used for the bouncing dots.
| role="img" | ||
| aria-label="google-icon-title" |
There was a problem hiding this comment.
For better accessibility, the Google icon inside the button should be considered decorative, as the button already has descriptive text ("Login with Google"). Decorative SVGs should be hidden from screen readers to prevent redundant announcements.
You can achieve this by removing the role and aria-label attributes and adding aria-hidden="true". The current aria-label="google-icon-title" is also not descriptive.
aria-hidden="true"|
Looks to much like the landing page. How bout you remove the header and footer from this one? |
i thought that would look consistent across all pages. this gives the effect of hero content changing into login with a smooth transition effect |
ahh. but keeping the header with login, signup button there when already on |
@burgerphilic18 we can i have same looking different different headers for diff routes |
|
@burgerphilic18 any updates? |
bhaiya I got back in bme so I haven't done anything after results |
Description
This PR adds the login page which allows signing in with Google account. The user is redirected to
/auth/googleto complete the sign in step. Follows the same design language as landing pageScreenshots
Light Mode
Dark Mode
Issue
solves #24