From be5ffbd82a02c10a03d318ce42d4ba291282e2ab Mon Sep 17 00:00:00 2001 From: likithayadav_g Date: Fri, 23 Jan 2026 11:46:29 +0530 Subject: [PATCH 1/2] feat(sign-in-page): implement sign-in page with email and password inputs, Google sign-in button and tests --- src/components/googlelogo/GoogleLogo.test.tsx | 43 +++++++++ src/components/googlelogo/GoogleLogo.tsx | 32 +++++++ src/features/auth/SignInPage.test.tsx | 69 ++++++++++++++ src/features/auth/SignInPage.tsx | 92 +++++++++++++++++++ 4 files changed, 236 insertions(+) create mode 100644 src/components/googlelogo/GoogleLogo.test.tsx create mode 100644 src/components/googlelogo/GoogleLogo.tsx create mode 100644 src/features/auth/SignInPage.test.tsx create mode 100644 src/features/auth/SignInPage.tsx diff --git a/src/components/googlelogo/GoogleLogo.test.tsx b/src/components/googlelogo/GoogleLogo.test.tsx new file mode 100644 index 0000000..0e416ca --- /dev/null +++ b/src/components/googlelogo/GoogleLogo.test.tsx @@ -0,0 +1,43 @@ +import { render } from "@testing-library/react"; +import { describe, it, expect } from "vitest"; +import { GoogleLogo } from "./GoogleLogo"; + +interface RenderOptions { + className?: string; +} + +const defaultProps: RenderOptions = { + className: "w-5 h-5", +}; + +const renderGoogleLogo = (additionalProps: RenderOptions = {}) => { + const props = { ...defaultProps, ...additionalProps }; + + return render(); +}; + +describe("GoogleLogo", () => { + it("should render an svg element", () => { + const { container } = renderGoogleLogo(); + + const svg = container.querySelector("svg"); + + expect(svg).toBeInTheDocument(); + }); + + it("should apply provided className when passed", () => { + const { container } = renderGoogleLogo({ className: "w-8 h-8" }); + + const svg = container.querySelector("svg"); + + expect(svg).toHaveClass("w-8"); + }); + + it("should be hidden from the accessibility tree", () => { + const { container } = renderGoogleLogo(); + + const svg = container.querySelector("svg"); + + expect(svg).toHaveAttribute("aria-hidden", "true"); + }); +}); diff --git a/src/components/googlelogo/GoogleLogo.tsx b/src/components/googlelogo/GoogleLogo.tsx new file mode 100644 index 0000000..9860ae0 --- /dev/null +++ b/src/components/googlelogo/GoogleLogo.tsx @@ -0,0 +1,32 @@ +type GoogleLogoProps = { + className?: string; +}; + +export const GoogleLogo = ({ className }: GoogleLogoProps) => { + return ( + + ); +}; diff --git a/src/features/auth/SignInPage.test.tsx b/src/features/auth/SignInPage.test.tsx new file mode 100644 index 0000000..7c78578 --- /dev/null +++ b/src/features/auth/SignInPage.test.tsx @@ -0,0 +1,69 @@ +import { render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { describe, it } from "vitest"; +import { BrowserRouter } from "react-router-dom"; +import { SignInPage } from "./SignInPage"; + +const renderSignInPage = () => { + return render( + + + , + ); +}; + +describe("SignInPage", () => { + it("should render the email input field", () => { + renderSignInPage(); + + expect(screen.getByLabelText(/email/i)).toBeInTheDocument(); + }); + + it("should render the password input field", () => { + renderSignInPage(); + + expect(screen.getByLabelText(/password/i)).toBeInTheDocument(); + }); + + it("should allow typing in the email input", async () => { + renderSignInPage(); + const user = userEvent.setup(); + + const emailInput = screen.getByLabelText(/email/i); + await user.type(emailInput, "test@example.com"); + + expect(emailInput).toHaveValue("test@example.com"); + }); + + it("should allow typing in the password input", async () => { + renderSignInPage(); + const user = userEvent.setup(); + + const passwordInput = screen.getByLabelText(/password/i); + await user.type(passwordInput, "password123"); + + expect(passwordInput).toHaveValue("password123"); + }); + + it("should render the sign in button", () => { + renderSignInPage(); + + expect( + screen.getByRole("button", { name: /sign in/i }), + ).toBeInTheDocument(); + }); + + it("should render the continue with google button", () => { + renderSignInPage(); + + expect( + screen.getByRole("button", { name: /continue with google/i }), + ).toBeInTheDocument(); + }); + + it("should render the sign up link", () => { + renderSignInPage(); + + expect(screen.getByRole("link", { name: /sign up/i })).toBeInTheDocument(); + }); +}); diff --git a/src/features/auth/SignInPage.tsx b/src/features/auth/SignInPage.tsx new file mode 100644 index 0000000..d11143b --- /dev/null +++ b/src/features/auth/SignInPage.tsx @@ -0,0 +1,92 @@ +import { useState } from "react"; +import { Link } from "react-router-dom"; +import { Button } from "../../components/button/Button"; +import { Input } from "../../components/input/Input"; +import { Card, CardBody } from "../../components/card/Card"; +import { GoogleLogo } from "../../components/googlelogo/GoogleLogo"; + +export const SignInPage = () => { + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + + const handleSubmit = (event: React.FormEvent) => { + event.preventDefault(); + }; + + return ( +
+
+ + +
+

+ Welcome Back +

+

+ Sign in to access your saved resources +

+
+ +
+ setEmail(event.target.value)} + className="w-full" + required + autoComplete="email" + /> + + setPassword(event.target.value)} + className="w-full" + required + autoComplete="current password" + /> + + +
+ +
+
+
+
+
+ + Or continue with + +
+
+ + + +

+ Don't have an account?{" "} + + Sign up + +

+ + +
+
+ ); +}; From 34933d815094af3277f867957f64d897a87f49c7 Mon Sep 17 00:00:00 2001 From: likithayadav_g Date: Fri, 23 Jan 2026 11:56:23 +0530 Subject: [PATCH 2/2] fix(layout): adjust layout structure for consistent styling and spacing in footer --- src/app/layout/Layout.tsx | 4 ++-- src/components/footer/Footer.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/layout/Layout.tsx b/src/app/layout/Layout.tsx index e8187e6..23b84f0 100644 --- a/src/app/layout/Layout.tsx +++ b/src/app/layout/Layout.tsx @@ -5,7 +5,7 @@ import { NavigationBar } from "../../components/navigation-bar/NavigationBar"; export const Layout = () => { return ( -
+
@@ -14,7 +14,7 @@ export const Layout = () => {
-
+