Skip to content

Darkmode and Spinner #40

Merged
Anujcodecraft merged 5 commits intoAnujcodecraft:mainfrom
Ashu-sCode:darkmode
Jul 31, 2025
Merged

Darkmode and Spinner #40
Anujcodecraft merged 5 commits intoAnujcodecraft:mainfrom
Ashu-sCode:darkmode

Conversation

@Ashu-sCode
Copy link
Contributor

@Ashu-sCode Ashu-sCode commented Jul 31, 2025

just implemented new reusable spinner component

🔍 Preview image

@netlify
Copy link

netlify bot commented Jul 31, 2025

Deploy Preview for manitstudyportal ready!

Name Link
🔨 Latest commit 36f75e3
🔍 Latest deploy log https://app.netlify.com/projects/manitstudyportal/deploys/688b4e52baab520008e77aa6
😎 Deploy Preview https://deploy-preview-40--manitstudyportal.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@Jatin917 Jatin917 self-requested a review July 31, 2025 13:05
@Anujcodecraft Anujcodecraft merged commit 971ec9c into Anujcodecraft:main Jul 31, 2025
4 of 6 checks passed
@Ashu-sCode
Copy link
Contributor Author

Hey! 👋
@Anujcodecraft
I just noticed that I accidentally left dev credentials and an uncommented line in the LoginPage.jsx.
Rather than opening a new PR, I'm sharing the corrected version of the file here below. Everything is now clean, and the login logic follows the proper student email check as expected.

Really sorry for the oversight! 🙏
Here's the updated file:

import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../context/AuthContext';

import React from 'react';
import GoogleAuthButton from '../components/GoogleButton';
import { REGEX_EMAIL_TYPE } from '../lib';
import toast from 'react-hot-toast';

const LoginPage = () => {
  const [formData, setFormData] = useState({
    email: '',
    password: ''
  });

  const [error, setError] = useState('');
  const [loading, setLoading] = useState(false);
  const navigate = useNavigate();
  const { login } = useAuth();

  const handleChange = (e) => {
    setFormData({
      ...formData,
      [e.target.name]: e.target.value
    });
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    setError('');
    setLoading(true);
    const email = formData.email;
    if (!REGEX_EMAIL_TYPE.test(email)) {
      toast("⚠️ Please use your student email id provided by the campus");
      setLoading(false);
      return;
    }

    try {
      const response = await fetch(`${import.meta.env.VITE_BASE_URL_BACKEND}/login`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(formData)
      });

      const data = await response.json();
      if (!response.ok) {
        throw new Error(data.message || 'Login failed');
      }

      login(data.user, data.token);
      navigate('/');
    } catch (err) {
      setError(err.message || 'Invalid email or password');
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="min-h-screen bg-gray-50 dark:bg-gray-900 flex justify-center items-center px-4 sm:px-6 lg:px-8 transition-colors">
      <div className="w-full max-w-md bg-white dark:bg-gray-800 rounded-lg shadow-md overflow-hidden">
        <div className="p-6 sm:p-8">
          <h2 className="text-2xl sm:text-3xl font-bold text-center text-gray-800 dark:text-gray-100 mb-6">Login</h2>

          {error && (
            <div className="bg-red-100 dark:bg-red-400/20 border border-red-400 dark:border-red-500 text-red-700 dark:text-red-300 px-4 py-3 rounded mb-4 text-sm sm:text-base">
              {error}
            </div>
          )}

          <form onSubmit={handleSubmit} className="space-y-4 sm:space-y-6">
            <div>
              <label className="block text-gray-700 dark:text-gray-300 text-sm sm:text-base font-medium mb-1 sm:mb-2" htmlFor="email">
                Email
              </label>
              <input
                className="w-full px-3 py-2 sm:px-4 sm:py-3 border border-gray-300 dark:border-gray-700 rounded-md shadow-sm placeholder-gray-400 dark:placeholder-gray-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-blue-500 focus:border-blue-500"
                id="email"
                name="email"
                type="email"
                placeholder="john@example.com"
                value={formData.email}
                onChange={handleChange}
                required
              />
            </div>

            <div>
              <label className="block text-gray-700 dark:text-gray-300 text-sm sm:text-base font-medium mb-1 sm:mb-2" htmlFor="password">
                Password
              </label>
              <input
                className="w-full px-3 py-2 sm:px-4 sm:py-3 border border-gray-300 dark:border-gray-700 rounded-md shadow-sm placeholder-gray-400 dark:placeholder-gray-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-blue-500 focus:border-blue-500"
                id="password"
                name="password"
                type="password"
                placeholder="********"
                value={formData.password}
                onChange={handleChange}
                required
              />
            </div>

            <div>
              <button
                className="w-full flex justify-center py-2 sm:py-3 px-4 border border-transparent rounded-md shadow-sm text-sm sm:text-base font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors duration-200"
                type="submit"
                disabled={loading}
              >
                {loading ? 'Logging in...' : 'Login'}
              </button>
            </div>
          </form>

          <div className="mt-4 sm:mt-6">
            <div className="relative">
              <div className="absolute inset-0 flex items-center">
                <div className="w-full border-t border-gray-300 dark:border-gray-700"></div>
              </div>
              <div className="relative flex justify-center text-sm">
                <span className="px-2 bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400">Or continue with</span>
              </div>
            </div>

            <div className="mt-4 sm:mt-6 w-full">
              <GoogleAuthButton className="w-full" />
            </div>
          </div>

          <div className="mt-4 sm:mt-6 text-center">
            <p className="text-sm sm:text-base text-gray-600 dark:text-gray-400">
              Don't have an account?{' '}
              <a
                href="/signup"
                className="font-medium text-blue-600 dark:text-blue-400 hover:text-blue-500 dark:hover:text-blue-300 transition-colors duration-200"
              >
                Sign up
              </a>
            </p>
          </div>
        </div>
      </div>
    </div>
  );
};

export default LoginPage;

Let me know if you'd prefer I push this directly to the branch instead.

@Anujcodecraft
Copy link
Owner

@Ashu-sCode thanks for that even i missed that thing... if i would love to contribute there are more issues aligned in the issue section and for good backend system do check github.com/jatin917/riverside-clone this repo

@Ashu-sCode
Copy link
Contributor Author

Yes I would Love to contribute, Let me check @Anujcodecraft

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants