Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions app/components/AppShell.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"use client";

import Navbar from "./Navbar";

export default function AppShell({ children }) {
return (
<div className="h-screen bg-white dark:bg-black text-black dark:text-white transition-colors overflow-hidden">
<Navbar />
<main className="pt-24 h-full overflow-y-auto">
{children}
</main>
</div>
);
}

49 changes: 49 additions & 0 deletions app/components/Navbar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"use client";

import Link from "next/link";
import Image from "next/image";
import { useTheme } from "@/app/providers/ThemeProvider";

export default function Navbar() {
const { theme, toggleTheme } = useTheme();

return (
<header className="absolute inset-x-0 top-0 z-50">
<nav className="flex items-center justify-between p-6 lg:px-8">
<Link href="/">
<Image
src="/logo.png"
alt="Amrita logo"
width={128}
height={128}
/>
</Link>

<div className="flex items-center gap-2">
{/* Theme Toggle */}
<button
onClick={toggleTheme}
className="rounded-full p-2
bg-gray-200 dark:bg-gray-800
text-black dark:text-white
shadow hover:scale-105 transition"
aria-label="Toggle theme"
>
<span className="material-icons">
{theme === "dark" ? "light_mode" : "dark_mode"}
</span>
</button>

<Link
href="/login"
className="bg-black dark:bg-gray-800
text-white rounded-xl p-2"
>
Login
</Link>
</div>
</nav>
</header>
);
}

2 changes: 2 additions & 0 deletions app/globals.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));


@theme {
--default-ring-color: var(--color-blue-200);
Expand Down
10 changes: 9 additions & 1 deletion app/layout.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import "./globals.css";
import { ThemeProvider } from "./providers/ThemeProvider";
import AppShell from "./components/AppShell";

export const metadata = {
title: "Amrita Placement Tracker",
Expand All @@ -9,7 +11,13 @@ export const metadata = {
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
<body>
<ThemeProvider>
<AppShell>
{children}
</AppShell>
</ThemeProvider>
</body>
</html>
);
}
116 changes: 47 additions & 69 deletions app/login/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import Link from "next/link";
import { useRouter } from "next/navigation";
import "material-icons/iconfont/material-icons.css";


import { useTheme } from "../providers/ThemeProvider";


export default function Login() {
useEffect(() => {
secureLocalStorage.clear();
Expand All @@ -34,6 +38,11 @@ export default function Login() {

const router = useRouter();


const { theme, toggleTheme } = useTheme();



const handleLogin = async (e) => {
e.preventDefault();

Expand Down Expand Up @@ -199,44 +208,9 @@ export default function Login() {
};

return (
<main className="flex h-screen flex-1 flex-col justify-center">
<header className="absolute inset-x-0 top-0 z-50">
<nav
className="flex items-center justify-between p-6 lg:px-8"
aria-label="Global"
>
<div className="lg:flex lg:gap-x-12">
<Link href={"/"}>
<Image
src="/logo.png"
alt="Amrita logo"
width={128}
height={128}
className="ml-auto mr-auto my-4"
/>
</Link>
</div>
<div className="flex flex-1 justify-end space-x-1">
<Link
replace={true}
href={"/register"}
className="bg-[#000000] text-[#ffffff] rounded-xl p-2 items-center align-middle flex flex-row hover:bg-[#3b3b3b] "
>
{"Register"}
<span className="material-icons ml-2">
app_registration
</span>
</Link>
<Link
href={"/"}
className="bg-[#000000] text-[#ffffff] rounded-xl p-2 items-center align-middle flex flex-row hover:bg-[#3b3b3b] "
>
<span className="material-icons">home</span>
</Link>
</div>
</nav>
</header>
<div className="border border-gray-300 rounded-2xl mx-auto w-11/12 sm:max-w-11/12 md:max-w-md lg:max-w-md backdrop-blur-xl bg-gray-50">
<main className="flex h-screen flex-1 flex-col justify-center bg-white dark:bg-black text-black dark:text-white">

<div className="border border-gray-300 dark:border-gray-700 rounded-2xl mx-auto w-11/12 sm:max-w-11/12 md:max-w-md lg:max-w-md backdrop-blur-xl bg-gray-50 dark:bg-gray-900">
<div
className="absolute inset-x-0 -top-10 -z-10 transform-gpu overflow-hidden blur-2xl"
aria-hidden="true"
Expand All @@ -252,45 +226,49 @@ export default function Login() {

<div className="mx-auto w-full sm:max-w-11/12 md:max-w-md lg:max-w-md">
<div className="flex flex-row justify-center">
<h1 className="px-4 py-4 w-full text-2xl font-semibold text-center">
<h1 className="px-4 py-4 w-full text-2xl font-semibold text-center text-black dark:text-white">
Sign In
</h1>
</div>
<hr className="border-gray-300 w-full" />
</div>

<div className="mt-10 mx-auto w-full sm:max-w-11/12 md:max-w-md lg:max-w-md px-6 pb-8 lg:px-8 ">
<form className="space-y-6" onSubmit={handleLogin}>
<div>
<label className="block text-md font-medium leading-6 text-black">
Email ID
</label>
<div className="mt-2">
<input
type="email"
autoComplete="email"
placeholder="Enter your Email ID"
onChange={(e) =>
setUserEmail(
e.target.value.toLowerCase(),
)
}
className={
"block text-lg w-full rounded-md py-2 px-2 text-black ring-1 ring-inset ring-bGray placeholder:text-gray-400 sm:text-md sm:leading-6 outline-none!" +
(!isValidEmail && userEmail
? " ring-red-500"
: isValidEmail && userEmail
? " ring-green-500"
: " ring-bGray")
}
required
/>
</div>
</div>
<div className="mt-10 mx-auto w-full sm:max-w-11/12 md:max-w-md lg:max-w-md px-6 pb-8 lg:px-8 ">
<form className="space-y-6" onSubmit={handleLogin}>
<div>
<label className="block text-md font-medium leading-6 text-black dark:text-white">
Email ID
</label>
<div className="mt-2">
<input
type="email"
autoComplete="email"
placeholder="Enter your Email ID"
onChange={(e) =>
setUserEmail(
e.target.value.toLowerCase(),
)
}
className={
"block text-lg w-full rounded-md border-0 py-2 px-2 " +
"bg-white dark:bg-gray-800 " +
"text-black dark:text-white " +
"ring-1 ring-inset ring-bGray " +
"placeholder:text-gray-400 outline-none!" +
(!isValidPassword && userPassword
? " ring-red-500"
: isValidPassword && userPassword
? " ring-green-500"
: "")
}
required
/>
</div>
</div>

<div>
<div className="flex items-center justify-between">
<label className="block text-md font-medium leading-6 text-black">
<label className="block text-md font-medium leading-6 text-black dark:text-white">
Password
</label>
<div className="text-md">
Expand Down Expand Up @@ -324,7 +302,7 @@ export default function Login() {
</div>
</div>

{/* <p className="mt-10 text-center text-md text-gray-500">
{/* <p className="mt-10 text-center text-md text-gray-500 dark: text-gray-400">
{"Don't have an account? "}
<Link className="font-semibold leading-6 text-blue-600 hover:underline" href="/register">Register</Link>
</p> */}
Expand Down
42 changes: 9 additions & 33 deletions app/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,50 +18,24 @@ export default function Welcome() {
}, []);

return (
<main>
<main className="bg-white dark:bg-black text-black dark:text-white">
<div data-aos="fade-in">
<header className="absolute inset-x-0 top-0 z-50">
<nav
className="flex items-center justify-between p-6 lg:px-8"
aria-label="Global"
>
<div className="lg:flex lg:gap-x-12">
<Link href={"/"}>
<Image
src="/logo.png"
alt="Amrita logo"
width={128}
height={128}
className="ml-auto mr-auto my-4"
/>
</Link>
</div>
<div className="lg:flex lg:flex-1 lg:justify-end">
<Link
href={"/login"}
className="bg-[#000000] text-[#ffffff] rounded-xl p-2 items-center align-middle flex flex-row hover:bg-[#3b3b3b] "
>
<span className="material-icons">login</span>
</Link>
</div>
</nav>
</header>

<div className="relative isolate px-6 lg:px-8 flex justify-center items-center h-screen m-auto pt-16">
<div className="relative isolate px-6 lg:px-8 flex justify-center items-center">
<div
className="absolute inset-x-0 px-20 -top-40 -z-10 transform-gpu overflow-hidden blur-2xl"
aria-hidden="true"
>
<div className="relative left-[calc(50%-11rem)] aspect-1155/678 w-[64%] -translate-x-1/2 rotate-[40deg] bg-linear-to-tr from-[#cea8a8] to-[#dea9a9] opacity-20" />
</div>

<div className="mx-auto max-w-2xl py-48 lg:py-56">
<div className="mx-auto max-w-2xl py-12 lg:py-16">
<div className="sm:mb-8 flex justify-center text-center">
<Link
href={"https://www.amrita.edu"}
target="_blank"
>
<div className="relative rounded-full px-3 py-2 my-8 text-sm leading-6 text-gray-600 ring-1 ring-gray-900/10 hover:ring-gray-900/20 items-center align-middle flex flex-row">
<div className="relative rounded-full px-3 py-2 my-8 text-sm leading-6 text-gray-700 dark:text-gray-300 ring-1 ring-gray-900/10 dark:ring-gray-700 hover:ring-gray-900/20 dark:hover:ring-gray-500 items-center align-middle flex flex-row">
{"Amrita Vishwa Vidyapeetham, Coimbatore"}
<span className="material-icons ml-2">
open_in_new
Expand All @@ -70,10 +44,10 @@ export default function Welcome() {
</Link>
</div>
<div className="text-center">
<h1 className="text-4xl font-bold tracking-tight text-gray-900 sm:text-6xl">
<h1 className="text-4xl font-bold tracking-tight text-gray-900 dark:text-white sm:text-6xl">
Amrita Placement Tracker
</h1>
<p className="mt-6 text-lg leading-8 text-gray-600">
<p className="mt-6 text-lg leading-8 text-gray-600 dark:text-gray-300">
One-stop platform to track all placement-related
information of CSE Department, Amrita Vishwa
Vidyapeetham, Coimbatore. Register to get
Expand All @@ -92,7 +66,7 @@ export default function Welcome() {
</Link>
<Link
href="/register"
className="text-lg font-semibold text-gray-900 items-center align-middle flex flex-row border border-gray-400 px-2 py-1 rounded-lg hover:bg-gray-100"
className="text-lg font-semibold text-gray-900 dark:text-white items-center align-middle flex flex-row border border-gray-400 px-2 py-1 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800"
>
<span className="material-icons mr-2">
app_registration
Expand All @@ -107,3 +81,5 @@ export default function Welcome() {
</main>
);
}


47 changes: 47 additions & 0 deletions app/providers/ThemeProvider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
"use client";

import { createContext, useContext, useEffect, useState } from "react";

const ThemeContext = createContext(null);

export function ThemeProvider({ children }) {
const [theme, setTheme] = useState("light");

useEffect(() => {
const savedTheme = localStorage.getItem("theme");
if (savedTheme === "dark") {
document.documentElement.classList.add("dark");
setTheme("dark");
}
}, []);

const toggleTheme = () => {
setTheme((prev) => {
const next = prev === "light" ? "dark" : "light";

if (next === "dark") {
document.documentElement.classList.add("dark");
} else {
document.documentElement.classList.remove("dark");
}

localStorage.setItem("theme", next);
return next;
});
};

return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}

export function useTheme() {
const ctx = useContext(ThemeContext);
if (!ctx) {
throw new Error("useTheme must be used inside ThemeProvider");
}
return ctx;
}

Loading