Loading...
;
+};
+
+export default AuthVerify;
diff --git a/src/Components/Confirmation.css b/src/Components/Confirmation.css
new file mode 100644
index 0000000..680a38e
--- /dev/null
+++ b/src/Components/Confirmation.css
@@ -0,0 +1,137 @@
+@import '@radix-ui/colors/black-alpha.css';
+@import '@radix-ui/colors/mauve.css';
+@import '@radix-ui/colors/violet.css';
+@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
+
+.AlertDialogOverlay {
+ background-color: rgba(0, 0, 0, 0.455);
+ position: fixed;
+ inset: 0;
+ animation: overlayShow 150ms cubic-bezier(0.16, 1, 0.3, 1);
+}
+
+.AlertDialogContent {
+ background-color: rgb(51, 55, 62);
+ font-family: "Poppins", sans-serif;
+ font-weight: 400;
+ font-style: normal;
+ color: white;
+ border-radius: 6px;
+ box-shadow: hsl(206 22% 7% / 35%) 0px 10px 38px -10px, hsl(206 22% 7% / 20%) 0px 10px 20px -15px;
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 90vw;
+ max-width: 500px;
+ max-height: 85vh;
+ padding: 25px;
+ animation: contentShow 150ms cubic-bezier(0.16, 1, 0.3, 1);
+ text-align: center;
+}
+
+.AlertDialogContent:focus {
+ outline: none;
+}
+
+.AlertDialogTitle {
+ margin: 0;
+ color: white;
+ font-size: 17px;
+ font-weight: 500;
+ font-family: "Poppins", sans-serif;
+ font-weight: 400;
+ font-style: normal;
+}
+
+.AlertDialogDescription {
+ margin-top: 10px;
+ margin-bottom: 20px;
+ color: white;
+ font-size: 15px;
+ line-height: 1.5;
+ font-family: "Poppins", sans-serif;
+ font-weight: 400;
+ font-style: normal;
+}
+
+.Button {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 4px;
+ padding: 0 15px;
+ font-size: 15px;
+ line-height: 1;
+ font-weight: 500;
+ height: 35px;
+ font-family: "Poppins", sans-serif;
+ font-weight: 400;
+ font-style: normal;
+}
+
+.Button.violet {
+ background-color: rgba(62, 216, 219, 0.866);
+ color: white;
+}
+
+.Button.violet:hover {
+ background-color: rgba(55, 191, 194, 0.866);
+}
+
+.Button.violet:focus {
+ box-shadow: 0 0 0 2px black;
+}
+
+.Button.mauve {
+ background-color: red;
+ color: white;
+}
+
+.Button.mauve:hover {
+ background-color: rgb(206, 5, 5);
+}
+
+.Button.mauve:focus {
+ box-shadow: 0 0 0 2px black;
+}
+
+.avatar-container {
+ display: flex;
+ justify-content: center;
+ margin-bottom: 15px;
+}
+
+.avatar {
+ width: 100px;
+ height: 100px;
+ border-radius: 50%;
+ object-fit: cover;
+}
+
+.button-container {
+ display: flex;
+ justify-content: center;
+ gap: 25px;
+ margin-top: 20px;
+}
+
+@keyframes overlayShow {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+@keyframes contentShow {
+ from {
+ opacity: 0;
+ transform: translate(-50%, -48%) scale(0.96);
+ }
+ to {
+ opacity: 1;
+ transform: translate(-50%, -50%) scale(1);
+ }
+}
\ No newline at end of file
diff --git a/src/Components/Confirmation.js b/src/Components/Confirmation.js
new file mode 100644
index 0000000..c7bc6a0
--- /dev/null
+++ b/src/Components/Confirmation.js
@@ -0,0 +1,64 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import * as AlertDialog from '@radix-ui/react-alert-dialog';
+
+const Confirmation = ({ response, username, onConfirm, onCancel }) => {
+ let message1 = '';
+
+ let avatar = null;
+ let realName = '';
+ if (response.ranking !== undefined) {
+ message1 = "Is this your LeetCode account?";
+ realName = response.realName;
+ avatar = response.userAvatar ? (
+ Loading...
;
+ if (error) return
-
CCS Coding Community
+
CCS Codeboard
diff --git a/src/Components/Monthly.js b/src/Components/Monthly.js
new file mode 100644
index 0000000..2eace8b
--- /dev/null
+++ b/src/Components/Monthly.js
@@ -0,0 +1,77 @@
+import React, { useEffect, useState } from 'react';
+import axios from 'axios';
+import defaultImage from '../assets/default_file.svg';
+import SERVER_URL from "../config.js";
+import './Leaderboard.css';
+
+const BASE_URL = SERVER_URL + 'api/leaderboard';
+
+const Monthly = () => {
+ const [data, setData] = useState([]);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
+
+ useEffect(() => {
+ axios.get(`${BASE_URL}/monthly/`)
+ .then(response => {
+ const dataArray = Object.keys(response.data).map(key => ({
+ id: key,
+ ...response.data[key]
+ }));
+ setData(dataArray);
+ setLoading(false);
+ })
+ .catch(error => {
+ setError(error);
+ setLoading(false);
+ });
+ }, []);
+
+ if (loading) return
Loading...
;
+ if (error) return
Error loading data: {error.message}
;
+
+ return (
+
+
CCS Ranking
+
Monthly Leaderboard
+
+
+
+ | Rank |
+ Profile |
+ Username |
+ Questions Solved |
+
+
+
+ {data.map((item, index) => (
+
+ |
+ {index === 0 && 1}
+ {index === 1 && 2}
+ {index === 2 && 3}
+ {index >= 3 && {index + 1}}
+ |
+
+ {!item.photo_url ? (
+
+ ) : (
+ { e.target.src = defaultImage }}
+ />
+ )}
+ |
+ {item.username} |
+ {item.ques_solv} |
+
+ ))}
+
+
+
+ );
+};
+
+export default Monthly;
diff --git a/src/Components/Navbar.css b/src/Components/Navbar.css
new file mode 100644
index 0000000..974df72
--- /dev/null
+++ b/src/Components/Navbar.css
@@ -0,0 +1,302 @@
+.NavBar {
+ border-right: var(--NAV-BORDER);
+ padding: 1rem;
+ background-color: var(--NAV-BGCOLOR);
+ width: 18rem;
+ min-width: 14rem;
+ box-sizing: border-box;
+ overflow-y: auto;
+ position: fixed;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ height: 100vh;
+ z-index: 1000;
+ transition: width 0.3s ease, height 0.3s ease, transform 0.3s ease;
+}
+.divider {
+ font-weight: 600;
+ pointer-events: none;
+ color: var(--CONTENT-H2-COLOR);
+}
+
+.NavBar > h2 {
+ font-weight: 500;
+ color: var(--NAV-COLOR);
+}
+
+.NavBar ul {
+ list-style-type: none;
+ padding: 0;
+ margin-top: 1rem;
+ flex-grow: 1;
+ display: flex;
+ flex-direction: column;
+}
+
+.NavBar li {
+ padding-bottom: 0.3rem;
+ margin-bottom: 1rem;
+ display: flex;
+ align-items: center;
+}
+
+.NavBar li a,
+.NavBar li span {
+ text-decoration: none;
+ color: var(--NAV-COLOR);
+ padding: 0.8rem;
+ display: flex;
+ align-items: center;
+ width: 100%;
+}
+
+.NavBar li a:hover {
+ background-color: var(--LINK-HOVER-BGCOLOR);
+ color: rgb(253, 254, 254);
+ cursor: pointer;
+ border-radius: 7px;
+}
+
+.NavBar li:active,
+.NavBar li a:active,
+.NavBar li span:active {
+ color: var(--LINK-ACTIVE-COLOR);
+}
+
+.NavBar li:focus,
+.NavBar li a:focus,
+.NavBar li span:focus {
+ background-color: var(--LINK-HOVER-BGCOLOR);
+ color: rgb(253, 254, 254);
+ outline-offset: 4px;
+ border-radius: 7px;
+}
+.nav-icon {
+ margin-right: 0.5rem;
+ font-size: 1.5rem;
+}
+
+.NavBar .logout-button-container {
+ display: flex;
+ justify-content: flex-end;
+}
+
+.NavBar .logout-button-container .logout-button {
+ background-color: rgba(62, 216, 219, 0.866);
+ color: white;
+ border: none;
+ padding: 0.5rem 1rem;
+ border-radius: 0.25rem;
+ margin-right: 1rem;
+ cursor: pointer;
+ font-size: 1rem;
+}
+
+.logout-icon {
+ font-size: 1.5rem;
+ margin-right: 0.5rem;
+}
+
+.logout-text {
+ display: inline;
+}
+@media (max-width: 1235px) {
+ .NavBar {
+ width: 100%;
+ height: 7rem;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ border-right: none;
+ border-bottom: var(--NAV-BORDER);
+ }
+
+ .NavBar ul {
+ flex-direction: row;
+ align-items: center;
+ width: 70%;
+ justify-content: space-around;
+ margin-top: 0;
+ }
+
+ .NavBar li {
+ margin: 0;
+ padding: 0;
+ }
+
+ .NavBar li a,
+ .NavBar li span {
+ padding: 0.2rem;
+ padding-bottom: 0;
+ }
+
+ .nav-icon {
+ font-size: 1.5rem;
+ margin: 0;
+ }
+
+ .ccsLogo {
+ height: 4.5rem;
+ margin-left: 0.5rem;
+ }
+
+ .NavBar > h2,
+ .NavBar li a span,
+ .NavBar li span span {
+ display: none;
+ }
+
+ .NavBar .divider {
+ display: none;
+ }
+}
+
+@media (max-width: 768px) {
+ .NavBar {
+ height: auto;
+ padding: 0.5rem;
+ }
+
+ .NavBar ul {
+ flex-wrap: wrap;
+ }
+
+ .NavBar li {
+ margin: 0.25rem;
+ }
+
+ .ccsLogo {
+ height: 3.5rem;
+ }
+}
+
+ @media (max-width: 1235px) {
+ .NavBar {
+ width: 100%;
+ height: 7rem;
+ position: fixed;
+ top: 0;
+ left: 0;
+ background-color: var(--NAV-BGCOLOR);
+ padding: 0;
+ overflow: hidden;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ z-index: 1000;
+ border-right: none;
+ border-bottom: var(--NAV-BORDER);
+ }
+
+ .NavBar ul {
+ display: flex;
+ flex-direction: row;
+ align-items: right;
+ width: 70%;
+ justify-content: space-around;
+ }
+
+ .NavBar li {
+ margin: 0;
+ padding: 0;
+ }
+
+ .NavBar li a,
+ .NavBar li span {
+ padding: 0.2rem;
+ padding-bottom: 0;
+ }
+
+ .nav-icon {
+ font-size: 1.5rem;
+ margin: 0;
+ }
+
+ .ccsLogo {
+ margin-top: 1rem;
+ height: 4.5rem;
+ margin-left: 0.5rem;
+ }
+
+ .NavBar > h2,
+ .NavBar li a span,
+ .NavBar li span span {
+ display: none;
+ }
+
+ .NavBar .divider {
+ display: none;
+ }
+ }
+
+ @media (max-width: 768px) {
+ .NavBar .logout-button-container .logout-button {
+ font-size: 0.75rem;
+ padding: 0.15rem 0.4rem;
+ }
+ }
+
+
+.NavBar .logout-button-container .logout-button {
+ display: flex;
+ align-items: center;
+ background-color: rgba(62, 216, 219, 0.866);
+ color: white;
+ border: none;
+ padding: 0.5rem 1rem;
+ border-radius: 0.25rem;
+ cursor: pointer;
+ font-size: 1rem;
+ }
+
+ .logout-icon {
+ font-size: 1.5rem;
+ margin-right: 0.5rem;
+ }
+
+ .logout-text {
+ display: inline;
+ }
+
+ @media (max-width: 1235px) {
+ .logout-text {
+ display: none;
+ }
+ .NavBar .logout-button-container .logout-button {
+ background-color: transparent;
+ margin-top: 0.7rem;
+ }
+ .logout-button {
+ padding: 0.5rem;
+ background-color: transparent;
+ }
+
+ .logout-icon {
+ font-size: 1.5rem;
+ }
+ }
+
+
+@media (max-width: 1235px) {
+ .content {
+ margin-left: 0;
+ margin-top: 7rem;
+ }
+}
+
+@media (max-width: 768px) {
+ .content {
+ margin-top: 8rem;
+ }
+}
+@media (max-width: 768px) {
+ .NavBar .logout-button-container .logout-button {
+ font-size: 0.75rem;
+ padding: 0.15rem 0.2rem;
+ }
+}
\ No newline at end of file
diff --git a/src/Components/Navbar.js b/src/Components/Navbar.js
new file mode 100644
index 0000000..d64568f
--- /dev/null
+++ b/src/Components/Navbar.js
@@ -0,0 +1,89 @@
+import React from 'react';
+import { Link, useNavigate } from 'react-router-dom';
+import { FaCalendarDay, FaCalendarWeek, FaCalendarAlt, FaSignOutAlt } from 'react-icons/fa';
+import { MdAccountCircle,MdExitToApp } from 'react-icons/md';
+import ccsLogo from '../assets/ccs_logo.png';
+import SERVER_URL from "../config.js";
+import './Navbar.css';
+
+const API_URL = `${SERVER_URL}api/auth`;
+
+export default function Navbar() {
+ const navigate = useNavigate();
+
+ const handleLogout = async () => {
+ const token = localStorage.getItem('token');
+
+ try {
+ // console.log('Stored Token:', token);
+
+ const response = await fetch(API_URL + '/logout/', {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Token ${token}`,
+ },
+ });
+
+ if (!response.ok) {
+ throw new Error('Logout request failed');
+ }
+
+ const data = await response.json();
+ // console.log('Logout Response:', data);
+
+ if (data.message.toLowerCase() === 'logged out successfully') {
+ localStorage.removeItem('token');
+ localStorage.removeItem('isNewUser')
+ navigate('/login');
+ } else {
+ throw new Error('Logout failed');
+ }
+ } catch (error) {
+ console.error('Error logging out:', error);
+ // Optionally, you can navigate to login or show a user-friendly message
+ navigate('/login');
+ }
+ };
+
+ return (
+
+

+
+ - DASHBOARD
+ -
+
+
+ Profile
+
+
+
+ - LEADERBOARD
+ -
+
+
+ Daily
+
+
+ -
+
+
+ Weekly
+
+
+ -
+
+
+ Monthly
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/Components/Profile.css b/src/Components/Profile.css
new file mode 100644
index 0000000..c6bace5
--- /dev/null
+++ b/src/Components/Profile.css
@@ -0,0 +1,235 @@
+/* Profile ****************/
+.profile-container {
+ display: flex;
+ justify-content: space-between; /* Space between containers */
+ background-color: #282c34;
+ color: var(--CONTENT-COLOR);
+ padding: 2rem;
+ border-radius: 8px;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+ /* Adjusted width to fit both containers */
+ margin: 0 auto;
+ margin-top: 50px; /* Add margin-top for centering */
+ position: relative; /* Ensure it's centered vertically */
+ }
+
+ .detail-container {
+ flex: 1; /* Flex to adjust with the container */
+ text-align: center;
+ padding-right: 1rem; /* Padding to add space between containers */
+ }
+
+ .detail-container img {
+ border-radius: 50%;
+ width: 150px;
+ height: 150px;
+ object-fit: cover;
+ margin-bottom: 20px;
+ border: 3px solid var(--CONTENT-H2-COLOR); /* Add border */
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* Add shadow */
+ }
+
+ .detail-container h1 {
+ font-size: 2.5em; /* Increase font size */
+ color: white; /* Change name color to white */
+ margin-bottom: 10px;
+ }
+
+ .detail-container p {
+ font-size: 1.2em;
+ color: var(--CONTENT-COLOR);
+ margin: 5px 0;
+ }
+
+ .detail-container p span {
+ font-weight: bold;
+ color: white; /* Ensure high contrast */
+ font-family: "Poppins", sans-serif;
+ font-weight: 400;
+ font-style: normal;
+ }
+
+ /* Loading and Error Styles */
+ .loading,
+ .error {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+ font-size: 1.5em;
+ color: rgb(33, 35, 42);
+ }
+
+ /* Rank Slider ****************/
+ .rank-slider button {
+ background: none;
+ border: none;
+ padding: 0;
+ cursor: pointer;
+ font: inherit;
+ outline: inherit;
+ }
+ .rank-slider {
+ display: flex;
+ justify-content: center;
+ margin-bottom: 20px;
+ }
+
+ .rank-slider .tab {
+ text-decoration: none; /* Remove default underline */
+ color: var(--CONTENT-COLOR);
+ padding: 10px 20px;
+ margin: 0 5px;
+ border: none;
+ border-radius: 5px;
+ cursor: pointer;
+ font-size: 1rem;
+ transition: text-decoration-color 0.3s; /* Add transition for underline color */
+ }
+
+ .rank-slider .tab.active {
+ text-decoration: underline; /* Underline when active */
+ text-decoration-color: rgba(62, 216, 219, 0.866); /* Active underline color */
+ text-underline-offset: 2px; /* Optional: adjust underline position */
+ }
+
+ /* Responsive Design for Rank Slider */
+ @media (max-width: 768px) {
+ .rank-slider .tab {
+ padding: 5px 10px;
+ font-size: 0.875rem;
+ }
+ }
+
+ /* Adding responsive design */
+ @media (max-width: 768px) {
+ .profile-container {
+ padding: 1rem;
+ margin-top: 2rem;
+ }
+
+ .profile-container h1 {
+ font-size: 1.5em;
+ }
+
+ .profile-container p {
+ font-size: 1em;
+ }
+ }
+
+ .question-container {
+ flex: 2; /* Flex to adjust with the container */
+ }
+
+ .question-container h2 {
+ color: white !important; /* Change heading color to white */
+ text-align: center;
+ margin-bottom: 0.5rem;
+ font-family: "Poppins", sans-serif;
+ font-weight: 400;
+ font-style: normal;
+ }
+
+ /* LEADERBOARD ****************/
+ .questions-table,
+ .leaderboard-table {
+ width: 100%;
+ border-collapse: collapse;
+ background-color: var(--NAV-BGCOLOR);
+ color: var(--CONTENT-COLOR);
+ border: 2px solid rgba(62, 216, 219, 0.866);
+ border-radius: 1rem;
+ overflow: hidden; /* Ensure the border-radius applies to the entire table */
+ }
+
+ .questions-table th,
+ .questions-table td,
+ .leaderboard-table th,
+ .leaderboard-table td {
+ padding: 0.9375rem; /* 15px in rem */
+ text-align: left;
+ border-top: 0.0625rem solid rgba(62, 216, 219, 0.866); /* 1px in rem */
+ }
+
+ .questions-table a {
+ color: white; /* Change link color to white */
+ text-decoration: none; /* Remove underline if desired */
+ }
+
+ .questions-table a:hover {
+ text-decoration: underline; /* Optional: Add underline on hover */
+ color: rgba(62, 216, 219, 0.866); /* Optional: Change color on hover */
+ }
+
+ .questions-table th,
+ .leaderboard-table th {
+ background-color: var(--NAV-BGCOLOR);
+ color: white;
+ text-align: center;
+ }
+
+ /* Responsive Design for Leaderboard */
+ @media (max-width: 768px) {
+ .profile-container {
+ padding: 1rem; /* Equal padding on all sides */
+ margin: 0;
+ }
+
+ .content {
+ padding: 0.5rem; /* Equal padding on all sides */
+ margin: 0; /* Remove any extra margin */
+ }
+ .question-container,
+ .leaderboard-container {
+ padding: 1rem; /* Adjust padding for smaller screens */
+ margin: 0.5rem; /* Adjust margin for smaller screens */
+ }
+ .question-container h2,
+ .leaderboard-title-heading,
+ .leaderboard-title {
+ font-size: 0.875rem; /* Adjust font size for smaller screens */
+ text-align: center !important; /* Center-align text for smaller screens */
+ }
+ .questions-table th,
+ .questions-table td,
+ .leaderboard-table th,
+ .leaderboard-table td {
+ padding: 0.5rem; /* Reduce padding for smaller screens */
+ font-size: 0.75rem; /* Reduce font size for smaller screens */
+ text-align: center;
+ }
+
+ .leaderboard-row img {
+ width: 2rem; /* Reduce image size for smaller screens */
+ height: 2rem; /* Reduce image size for smaller screens */
+ }
+ .questions-table,
+ .leaderboard-table {
+ width: 100%; /* Ensure the table width fits within the container */
+ table-layout: fixed; /* Ensure consistent table cell widths */
+ }
+ .questions-table th,
+ .questions-table td,
+ .leaderboard-table th,
+ .leaderboard-table td {
+ white-space: normal; /* Allow text to wrap within cells */
+ word-wrap: break-word; /* Ensure long words are wrapped */
+ }
+ }
+
+ @media (max-width: 768px) {
+ .profile-container {
+ flex-direction: column;
+ align-items: center;
+ }
+
+ .detail-container {
+ padding-right: 0;
+ margin-bottom: 1rem; /* Add space between the containers */
+ }
+
+ .question-container {
+ width: 100%; /* Ensure the question container takes full width */
+ }
+ }
+
\ No newline at end of file
diff --git a/client/src/Components/Profile.js b/src/Components/Profile.js
similarity index 53%
rename from client/src/Components/Profile.js
rename to src/Components/Profile.js
index 9067a85..870db90 100644
--- a/client/src/Components/Profile.js
+++ b/src/Components/Profile.js
@@ -1,22 +1,25 @@
import React, { useState, useEffect } from 'react';
import SERVER_URL from "../config.js";
-const BASE_URL = SERVER_URL+'/api/leaderboard';
+import './Profile.css';
+
+const BASE_URL = SERVER_URL + 'api/leaderboard';
const Profile = () => {
const [profile, setProfile] = useState(null);
const [questions, setQuestions] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
+ const [rankPeriod, setRankPeriod] = useState('today');
useEffect(() => {
const fetchProfile = async () => {
- console.log('Fetching profile...');
+ // console.log('Fetching profile...');
const token = localStorage.getItem('token');
- console.log(token);
+ // console.log('Token:', token);
if (!token) {
setError('Token is missing');
setLoading(false);
- window.location.href="/login";
+ window.location.href = "/login";
return;
}
@@ -29,25 +32,29 @@ const Profile = () => {
}
});
- if (!response.ok) {
+ if (response.status === 401 || response.status === 404 || response.status === 400) {
+ window.location.href = "/login";
+ localStorage.removeItem('token');
+ return;
+ }
+ else if (!response.ok) {
throw new Error(`Error: ${response.status}`);
}
const data = await response.json();
- console.log('Response received:', data);
+ // console.log('Profile response received:', data);
setProfile(data);
- console.log('Profile data set:', data);
} catch (err) {
console.error('Error occurred:', err);
- setError(err);
+ setError(err.message);
} finally {
setLoading(false);
- console.log('Loading state set to false');
+ // console.log('Loading state set to false');
}
};
const fetchQuestions = async () => {
- console.log('Fetching questions...');
+ // console.log('Fetching questions...');
const token = localStorage.getItem('token');
if (!token) {
setError('Token is missing');
@@ -68,45 +75,55 @@ const Profile = () => {
}
const data = await response.json();
- console.log('Questions response received:', data);
+ // console.log('Questions response received:', data);
setQuestions(data);
- console.log('Questions data set:', data);
} catch (err) {
console.error('Error occurred:', err);
- setError(err);
+ setError(err.message);
}
};
fetchProfile();
fetchQuestions();
- }, []);
+ }, []); // Fetch profile and questions only once on component mount
+
+ const showRank = (period) => {
+ setRankPeriod(period);
+ };
if (loading) {
- console.log('Loading...');
+ // console.log('Loading...');
return
Loading...
;
}
+
if (error) {
- console.error('Error:', error.message);
- return
Error: {error.message}
;
+ console.error('Error:', error);
+ return
Error: {error}
;
}
+
if (!profile) {
- console.log('No profile data available');
+ // console.log('No profile data available');
return
No profile data available
;
}
- console.log('Rendering profile:', profile);
- console.log('Rendering questions:', questions);
+ /* console.log('Rendering profile:', profile);
+ console.log('Rendering questions:', questions); */
return (
-

+ {profile.photo_url &&

}
{profile.name}
-
LeetCode Username: {profile.username}
-
LeetCode Rank: {profile.leetcode_rank}
-
Today's Rank: {profile.daily_rank}
-
Weekly Rank: {profile.weekly_rank}
-
Monthly Rank: {profile.monthly_rank}
+
Username: {profile.username}
+
+ {rankPeriod === 'today' &&
Today's Rank: {profile.daily_rank}
}
+ {rankPeriod === 'weekly' &&
Weekly Rank: {profile.weekly_rank}
}
+ {rankPeriod === 'monthly' &&
Monthly Rank: {profile.monthly_rank}
}
+
+
+
+
+
@@ -117,18 +134,20 @@ const Profile = () => {
Question |
Difficulty |
Status |
-
Link |
- {questions.map((question, index) => (
+ {questions.length > 0 ? questions.map((question, index) => (
- | {question.title} |
+ {question.title} |
{question.difficulty} |
{question.status} |
- View |
- ))}
+ )) : (
+
+ | No questions available |
+
+ )}
diff --git a/src/Components/ProfileNew.css b/src/Components/ProfileNew.css
new file mode 100644
index 0000000..581f524
--- /dev/null
+++ b/src/Components/ProfileNew.css
@@ -0,0 +1,144 @@
+/* Profile ****************/
+.profile-container {
+ display: flex;
+ justify-content: space-between; /* Space between containers */
+ background-color: #282c34;
+ color: var(--CONTENT-COLOR);
+ padding: 2rem;
+ border-radius: 8px;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+ /* Adjusted width to fit both containers */
+ margin: 0 auto;
+ margin-top: 50px; /* Add margin-top for centering */
+ position: relative; /* Ensure it's centered vertically */
+ }
+
+ .detail-container {
+ flex: 1; /* Flex to adjust with the container */
+ text-align: center;
+ padding-right: 1rem; /* Padding to add space between containers */
+ }
+
+ .detail-container img {
+ border-radius: 50%;
+ width: 150px;
+ height: 150px;
+ object-fit: cover;
+ margin-bottom: 20px;
+ border: 3px solid var(--CONTENT-H2-COLOR); /* Add border */
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* Add shadow */
+ }
+
+ .detail-container h1 {
+ font-size: 2.5em; /* Increase font size */
+ color: white; /* Change name color to white */
+ margin-bottom: 10px;
+ }
+
+ .detail-container p {
+ font-size: 1.2em;
+ color: var(--CONTENT-COLOR);
+ margin: 5px 0;
+ }
+
+ .detail-container p span {
+ font-weight: bold;
+ color: white; /* Ensure high contrast */
+ font-family: "Poppins", sans-serif;
+ font-weight: 400;
+ font-style: normal;
+ }
+
+
+ .question-container {
+ flex: 2; /* Flex to adjust with the container */
+ }
+
+ .question-container h2 {
+ color: white; /* Change heading color to white */
+ text-align: center;
+ margin-bottom: 0.5rem;
+ font-family: "Poppins", sans-serif;
+ font-weight: 400;
+ font-style: normal;
+ }
+ .questions-table,
+.leaderboard-table {
+ width: 100%;
+ border-collapse: collapse;
+ background-color: var(--NAV-BGCOLOR);
+ color: var(--CONTENT-COLOR);
+ border: 2px solid rgba(62, 216, 219, 0.866);
+ border-radius: 1rem;
+ overflow: hidden; /* Ensure the border-radius applies to the entire table */
+
+}
+
+.questions-table th,
+.questions-table td,
+.leaderboard-table th,
+.leaderboard-table td {
+ padding: 0.9375rem; /* 15px in rem */
+ text-align: centre;
+ border-top: 0.0625rem solid rgba(62, 216, 219, 0.866); /* 1px in rem */
+}
+.questions-table th:first-child,
+.questions-table td:first-child{
+ text-align: left;
+}
+.questions-table a {
+ color: white; /* Change link color to white */
+ text-decoration: none; /* Remove underline if desired */
+}
+
+.questions-table a:hover {
+ text-decoration: underline; /* Optional: Add underline on hover */
+ color: rgba(62, 216, 219, 0.866); /* Optional: Change color on hover */
+}
+.questions-table th,
+.leaderboard-table th {
+ background-color: var(--NAV-BGCOLOR);
+ color: white;
+ text-align: center;
+}
+
+ /* Rank Slider ****************/
+ .rank-slider button {
+ background: none;
+ border: none;
+ padding: 0;
+ cursor: pointer;
+ font: inherit;
+ outline: inherit;
+}
+.rank-slider {
+ display: flex;
+ justify-content: center;
+ margin-bottom: 20px;
+}
+
+.rank-slider .tab {
+ text-decoration: none; /* Remove default underline */
+ color: var(--CONTENT-COLOR);
+ padding: 10px 20px;
+ margin: 0 5px;
+ border: none;
+ border-radius: 5px;
+ cursor: pointer;
+ font-size: 1rem;
+ transition: text-decoration-color 0.3s; /* Add transition for underline color */
+}
+
+.rank-slider .tab.active {
+ text-decoration: underline; /* Underline when active */
+ text-decoration-color: rgba(62, 216, 219, 0.866); /* Active underline color */
+ text-underline-offset: 2px; /* Optional: adjust underline position */
+}
+
+/* Responsive Design for Rank Slider */
+@media (max-width: 768px) {
+ .rank-slider .tab {
+ padding: 5px 10px;
+ font-size: 0.875rem;
+ }
+}
diff --git a/src/Components/UsernameEntry.js b/src/Components/UsernameEntry.js
new file mode 100644
index 0000000..dd92f3e
--- /dev/null
+++ b/src/Components/UsernameEntry.js
@@ -0,0 +1,225 @@
+import React, { useEffect, useState } from 'react';
+import { useNavigate, useLocation } from 'react-router-dom';
+import SERVER_URL from "../config.js";
+import ccsLogoBulb from '../assets/ccs-bulb.png';
+import Confirmation from './Confirmation';
+import './UsernameForm.css';
+
+const API_URL = SERVER_URL + 'api/auth';
+
+const UsernameEntry = ({ setIsAuthenticated }) => {
+ const location = useLocation();
+ const { userData, token: locationToken } = location.state || {};
+ const [leetcodeUsername, setLeetcodeUsername] = useState('');
+ const [showConfirmation, setShowConfirmation] = useState(false);
+ const [verificationResponse, setVerificationResponse] = useState({});
+ const navigate = useNavigate();
+
+ useEffect(() => {
+ document.body.classList.add('username-entry-body');
+ return () => {
+ document.body.classList.remove('username-entry-body');
+ };
+ }, []);
+
+ const handleUsernameChange = (e) => {
+ setLeetcodeUsername(e.target.value);
+ };
+
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+
+ const token = locationToken || localStorage.getItem('token');
+ if (!token) {
+ console.error('Token is missing');
+ navigate('/login');
+ return;
+ }
+
+ const payload = {
+ leetcode_username: leetcodeUsername,
+ token: token
+ };
+
+ const requestOptions = {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Token ${token}`
+ },
+ body: JSON.stringify(payload)
+ };
+
+ try {
+ const verifyResponse = await fetch(`${API_URL}/verify-leetcode/`, requestOptions);
+ if (!verifyResponse.ok) {
+ throw new Error('Verification failed');
+ }
+
+ const verifyData = await verifyResponse.json();
+ setVerificationResponse(verifyData);
+ setShowConfirmation(true);
+ } catch (error) {
+ console.error('Error:', error.message);
+ alert('An error occurred. Please try again.');
+ }
+ };
+
+ const handleConfirm = async () => {
+ const token = locationToken || localStorage.getItem('token');
+ const payload = {
+ leetcode_username: leetcodeUsername,
+ token: token
+ };
+
+ const requestOptions = {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Token ${token}`
+ },
+ body: JSON.stringify(payload)
+ };
+
+ try {
+ const registerResponse = await fetch(`${API_URL}/register-leetcode/`, requestOptions);
+ if (!registerResponse.ok) {
+ throw new Error('Registration failed');
+ }
+
+ const registerData = await registerResponse.json();
+ // console.log('Registration successful. Redirecting to profile...');
+
+ await localStorage.setItem('token', token);
+ const storedToken = localStorage.getItem('token');
+ // console.log('Stored token:', storedToken);
+
+ setIsAuthenticated(true);
+ navigate('/profile');
+ } catch (error) {
+ console.error('Error:', error);
+ alert('An error occurred. Please try again.');
+ }
+ };
+
+ const handleCancel = () => {
+ setShowConfirmation(false);
+ };
+
+ return (
+
+
+
+ {/* Left side content */}
+
+
+
+

+
+
+
Single Sign On
+ Simplifying access across CCS
+
+
+
+
+
+
+
Welcome, {userData ? userData.fullName : 'User'}!
+
Please accept the OAuth policy and provide additional information.
+
+
+
+
+
+ {/* Right side form */}
+
+
+
+ {showConfirmation && (
+
+ )}
+
+
+ );
+};
+
+export default UsernameEntry;
\ No newline at end of file
diff --git a/src/Components/UsernameForm.css b/src/Components/UsernameForm.css
new file mode 100644
index 0000000..bbde45c
--- /dev/null
+++ b/src/Components/UsernameForm.css
@@ -0,0 +1,494 @@
+
+/* UsernameEntry styles *****************************************/
+body.username-entry-body {
+ background-color: black; /* Black background for the body */
+ color: var(--text-color); /* White text color */
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+ padding: 0;
+ margin: 0;
+ }
+ .container {
+ background-color: var(--cont-color);
+ border-radius: 8px;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+ padding: 30px;
+ max-width: 1000px;
+ width: 100%;
+ text-align: center;
+ display: flex;
+ justify-content: space-evenly;
+ align-items: stretch;
+ flex-wrap: wrap;
+ }
+
+ /* Left Column Styles */
+ .left {
+ display: flex;
+ flex-direction: column;
+ width: 45%;
+
+ border-radius: 8px 0 0 8px;
+ align-items: center;
+ gap: 30px;
+ background: var(--cont-color);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ padding: 12px;
+ }
+
+ .left-top {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ width: 100%;
+ margin-top: 30px;
+ gap: 15px;
+ text-align: center;
+ }
+
+ .left-top h1 {
+ font-size: 32px;
+ color: var(--ac-color);
+ margin: 0;
+ font-weight: 700;
+ }
+
+ .left-top h2 {
+ font-size: 16px;
+ color: white !important;
+ font-weight: 500;
+ }
+
+ .left-bottom {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+
+ width: 100%;
+ }
+
+ .left-bottom h4 {
+ font-size: 20px;
+ color: var(--ac-color);
+
+ font-weight: 600;
+ }
+
+ .logo img {
+ width: 5rem;
+ border-radius: 50%;
+ }
+
+ .left-bottom .content {
+ display: flex;
+ align-items: center;
+ margin: 0.5rem;
+ padding: 0.4rem;
+ }
+
+ .profile {
+ width: 60px;
+ height: 60px;
+ margin-right: 10px; /* Adjust margin as needed */
+ }
+
+ .content-left {
+ flex: 1; /* Take up remaining space */
+
+ }
+ @media (max-width: 1024px) {
+ .outer-container{
+ width: 90%;
+ }
+ }
+ /* Adjustments for smaller screens */
+ @media (max-width: 768px) {
+ .outer-container{
+ width: 82%;
+ margin-top: 20rem;
+ }
+ .left {
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+ }
+
+ .content {
+ flex-direction: column;
+ align-items: center;
+ }
+
+ .profile {
+ margin-bottom: 10px; /* Adjust margin for spacing */
+ }
+ }
+ /* Right Column Styles */
+ .right {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 15px;
+ margin-left: 8px;
+ width: 50%;
+ margin-bottom: 8px;
+ }
+
+ /* Form Styles */
+ .user-form {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ width: 100%;
+ height: 100%;
+ justify-content: space-between;
+ }
+
+ .input-group-row {
+ display: flex;
+ gap: 15px;
+ }
+
+ .input-group {
+ position: relative;
+ margin-top: 10px;
+ height: 56px;
+ }
+
+ .input-group input,
+ .input-group select {
+ width: 100%;
+ height: 100%;
+ padding: 0 10px;
+ border: 1px solid var(--ac-color);
+ border-radius: 4px;
+ font-size: 14px;
+ line-height: 56px;
+ background-color: var(--cont-color);
+ color: var(--text-color); /* White text color */
+ }
+ .input-group #roll-number,
+ .input-group #email{
+ color: rgb(179, 179, 179);
+ }
+
+ .input-group label {
+ position: absolute;
+ top: 0;
+ left: 0;
+ font-size: 12px;
+ color: var(--ac-color);
+ transform: translateY(-50%) scale(0.75) translateX(-5%);
+ background: var(--cont-color);
+ pointer-events: none;
+ transition: none;
+ }
+
+ .input-group input:focus ~ label,
+ .input-group input:not(:placeholder-shown) ~ label,
+ .input-group select:focus ~ label,
+ .input-group select:not([value=""]) ~ label {
+ top: 0;
+ }
+
+ .input-group select {
+ appearance: none;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='%235f6368' viewBox='0 0 16 16'%3E%3Cpath d='M7.247 11.14L2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z'/%3E%3C/svg%3E");
+ background-repeat: no-repeat;
+ background-position: right 10px center;
+ padding-right: 40px;
+ }
+ .input-group input:focus {
+ background-color: var(--cont-color); /* Dark background */
+ color: var(--text-color); /* White text */
+ border-color: var(--ac-color); /* Accent color border */
+ }
+
+ /* Optional: Style for when the input is not empty */
+ .input-group input:not(:placeholder-shown) {
+ background-color: var(--cont-color); /* Dark background */
+ color: var(--text-color); /* White text */
+ }
+ .input-group select option[disabled] {
+ display: none;
+ }
+
+ .input-group select:invalid {
+ color: #5f6368;
+ }
+
+ /* Policy Styles */
+ .policy {
+ display: flex;
+ align-items: center;
+ }
+
+ .policy label {
+ font-size: 14px;
+ color: #5f6368;
+ display: flex;
+ align-items: center;
+ }
+
+ .policy input[type="checkbox"] {
+ width: auto;
+ margin-right: 10px;
+ }
+
+ /* Button Styles */
+ button {
+ background-color: var(--ac-color);
+ color: #ffffff;
+ padding: 10px;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 16px;
+ }
+
+ button:hover {
+ background-color: #139ad6;
+ }
+
+ /* Media Queries */
+ @media (max-width: 768px) {
+
+ .container {
+ margin-top: 6rem;
+ flex-direction: column;
+ }
+
+ .left,
+ .right {
+ width: 100%;
+ margin: 0;
+ }
+ }
+
+ @media (max-width: 576px) {
+ .container {
+ box-shadow: none;
+ }
+
+ .left {
+
+ box-shadow: none;
+ }
+
+ .left-top h1 {
+ font-size: 24px;
+ }
+
+ .left-top h2 {
+ font-size: 14px;
+ }
+
+ .left-bottom h4 {
+ font-size: 18px;
+ }
+
+ .content p {
+ font-size: 14px;
+ }
+
+ .input-group label {
+ top: 0;
+ }
+
+ .input-group {
+ height: 45px;
+ }
+
+ .input-group input,
+ .input-group select {
+ width: 100%;
+ height: 40px;
+ padding: 0 10px;
+ border: 1px solid #39b9bc;
+ border-radius: 4px;
+ font-size: 14px;
+ line-height: 1.5;
+ background-color: var(--cont-color);
+ }
+
+ .policy label {
+ font-size: 12px;
+ }
+
+ button {
+ padding: 12px;
+ font-size: 16px;
+ }
+
+ .input-group label {
+ font-size: 12px;
+ }
+
+ .input-group input:focus ~ label,
+ .input-group input:not(:placeholder-shown) ~ label,
+ .input-group select:focus ~ label,
+ .input-group select:not([value=""]):not([value="Select your branch"]) ~ label {
+ font-size: 10px;
+ }
+ }
+
+ @media (max-width: 480px) {
+ .input-group-row {
+ flex-direction: column;
+ }
+
+ .input-group-row .input-group {
+ width: 100%;
+ }
+ }
+ @media (max-width: 600px) {
+ body{
+ background-color: rgb(18, 17, 17);
+ }
+ }
+ @media (max-width: 445px) {
+
+ .container {
+ margin-top: 0;
+ flex-direction: column;
+ }
+ }
+
+
+ /* CONFIRMATION POPUP */
+ .AlertDialogOverlay {
+ background-color: rgba(0, 0, 0, 0.455);
+ position: fixed;
+ inset: 0;
+ animation: overlayShow 150ms cubic-bezier(0.16, 1, 0.3, 1);
+ }
+
+ .AlertDialogContent {
+ background-color: rgb(51, 55, 62);
+ font-family: "Poppins", sans-serif;
+ font-weight: 400;
+ font-style: normal;
+ color: white;
+ border-radius: 6px;
+ box-shadow: hsl(206 22% 7% / 35%) 0px 10px 38px -10px, hsl(206 22% 7% / 20%) 0px 10px 20px -15px;
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 90vw;
+ max-width: 500px;
+ max-height: 85vh;
+ padding: 25px;
+ animation: contentShow 150ms cubic-bezier(0.16, 1, 0.3, 1);
+ text-align: center;
+ }
+
+ .AlertDialogContent:focus {
+ outline: none;
+ }
+
+ .AlertDialogTitle {
+ margin: 0;
+ color: white;
+ font-size: 17px;
+ font-weight: 500;
+ font-family: "Poppins", sans-serif;
+ font-weight: 400;
+ font-style: normal;
+ }
+
+ .AlertDialogDescription {
+ margin-top: 10px;
+ margin-bottom: 20px;
+ color: white;
+ font-size: 15px;
+ line-height: 1.5;
+ font-family: "Poppins", sans-serif;
+ font-weight: 400;
+ font-style: normal;
+ }
+
+ .Button {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 4px;
+ padding: 0 15px;
+ font-size: 15px;
+ line-height: 1;
+ font-weight: 500;
+ height: 35px;
+ font-family: "Poppins", sans-serif;
+ font-weight: 400;
+ font-style: normal;
+ }
+
+ .Button.violet {
+ background-color: rgba(62, 216, 219, 0.866);
+ color: white;
+ }
+
+ .Button.violet:hover {
+ background-color: rgba(55, 191, 194, 0.866);
+ }
+
+ .Button.violet:focus {
+ box-shadow: 0 0 0 2px black;
+ }
+
+ .Button.mauve {
+ background-color: red;
+ color: white;
+ }
+
+ .Button.mauve:hover {
+ background-color: rgb(206, 5, 5);
+ }
+
+ .Button.mauve:focus {
+ box-shadow: 0 0 0 2px black;
+ }
+
+ .avatar-container {
+ display: flex;
+ justify-content: center;
+ margin-bottom: 15px;
+ }
+
+ .avatar {
+ width: 100px;
+ height: 100px;
+ border-radius: 50%;
+ object-fit: cover;
+ }
+
+ .button-container {
+ display: flex;
+ justify-content: center;
+ gap: 25px;
+ margin-top: 20px;
+ }
+
+ @keyframes overlayShow {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+ }
+
+ @keyframes contentShow {
+ from {
+ opacity: 0;
+ transform: translate(-50%, -48%) scale(0.96);
+ }
+ to {
+ opacity: 1;
+ transform: translate(-50%, -50%) scale(1);
+ }
+ }
+
\ No newline at end of file
diff --git a/src/Components/Weekly.js b/src/Components/Weekly.js
new file mode 100644
index 0000000..3d70b7d
--- /dev/null
+++ b/src/Components/Weekly.js
@@ -0,0 +1,77 @@
+import React, { useEffect, useState } from 'react';
+import axios from 'axios';
+import defaultImage from '../assets/default_file.svg';
+import SERVER_URL from "../config.js";
+import './Leaderboard.css';
+
+const BASE_URL = SERVER_URL + 'api/leaderboard';
+
+const Weekly = () => {
+ const [data, setData] = useState([]);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
+
+ useEffect(() => {
+ axios.get(`${BASE_URL}/weekly/`)
+ .then(response => {
+ const dataArray = Object.keys(response.data).map(key => ({
+ id: key,
+ ...response.data[key]
+ }));
+ setData(dataArray);
+ setLoading(false);
+ })
+ .catch(error => {
+ setError(error);
+ setLoading(false);
+ });
+ }, []);
+
+ if (loading) return
Loading...
;
+ if (error) return
Error loading data: {error.message}
;
+
+ return (
+
+
CCS Ranking
+
Weekly Leaderboard
+
+
+
+ | Rank |
+ Profile |
+ Username |
+ Questions Solved |
+
+
+
+ {data.map((item, index) => (
+
+ |
+ {index === 0 && 1}
+ {index === 1 && 2}
+ {index === 2 && 3}
+ {index >= 3 && {index + 1}}
+ |
+
+ {!item.photo_url ? (
+
+ ) : (
+ { e.target.src = defaultImage }}
+ />
+ )}
+ |
+ {item.username} |
+ {item.ques_solv} |
+
+ ))}
+
+
+
+ );
+};
+
+export default Weekly;
diff --git a/src/Login.css b/src/Login.css
new file mode 100644
index 0000000..39ef3dc
--- /dev/null
+++ b/src/Login.css
@@ -0,0 +1,165 @@
+body.login-body {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+ margin: 0;
+ background-color: black;
+ color: white;
+ font-size: 1rem; /* Base font size */
+}
+
+.login-outer-container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ min-height: 100vh;
+ margin: 0 auto;
+}
+
+.login-container {
+ display: flex;
+ flex-direction: row;
+ background-color: rgb(18, 17, 17);
+ border-radius: 0.5rem; /* 8px => 0.5rem */
+ overflow: hidden;
+ box-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.1); /* 4px, 8px => 0.25rem, 0.5rem */
+ width: 100%;
+ max-width: 56.25rem; /* 900px => 56.25rem */
+ height: 60%;
+ z-index: 1;
+}
+
+.logo-section {
+ flex: 1;
+ padding-left: 2rem;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.ccs-logo {
+ max-width: 90%;
+ height: auto;
+}
+.logo-section p {
+ color: white;
+}
+.form-section {
+ flex: 1;
+ padding: 2.5rem; /* 40px => 2.5rem */
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+.form-section h2 {
+ text-align: center;
+ margin-bottom: 1.25rem; /* 20px => 1.25rem */
+ color: white;
+}
+
+.form-button {
+ width: 70%;
+ padding: 0.625rem; /* 10px => 0.625rem */
+ margin-top: 0.625rem; /* 10px => 0.625rem */
+ background-color: #4285f4;
+ color: white;
+ border: none;
+ border-radius: 0.5rem; /* 8px => 0.5rem */
+ cursor: pointer;
+}
+
+.form-button:hover {
+ background-color: #357ae8;
+}
+
+.ccs-login {
+ background-color: #34a853;
+}
+
+.ccs-login:hover {
+ background-color: #2b8e42;
+}
+
+/* Media Queries for responsiveness */
+@media (max-width: 768px) {
+ .login-container {
+ flex-direction: column;
+ height: auto;
+ margin-top: 1.25rem; /* 20px => 1.25rem */
+ margin: 1.25rem; /* 20px => 1.25rem */
+ width: 90%; /* Reduce container width */
+ }
+
+ .logo-section {
+ padding: 1.25rem; /* 20px => 1.25rem */
+ }
+
+ .ccs-logo {
+ max-width: 60%;
+ }
+
+ .form-section {
+ padding: 1.25rem; /* 20px => 1.25rem */
+ }
+
+ .form-button {
+ width: 90%;
+ padding: 0.5rem; /* 8px => 0.5rem */
+ margin-top: 0.5rem; /* 8px => 0.5rem */
+ font-size: 0.875rem; /* Smaller font size */
+ }
+
+ .form-section h2 {
+ font-size: 1.125rem; /* 18px => 1.125rem */
+ }
+}
+
+@media (max-width: 480px) {
+ .login-outer-container {
+ min-height: 100vh;
+ display: flex;
+ align-items: flex-start; /* Align to the top */
+ justify-content: center;
+ padding-top: 1vh; /* 1% of viewport height */
+ }
+
+ .login-container {
+ flex-direction: column;
+ height: auto;
+ width: 95%;
+ max-width: 100%; /* Ensure it doesn't exceed screen width */
+ margin: 0 auto; /* Center horizontally */
+ padding: 0.5rem;
+ }
+
+ .ccs-logo {
+ max-width: 50%;
+ }
+
+ .form-section {
+ padding: 0.625rem; /* 10px => 0.625rem */
+ }
+
+ .form-button {
+ width: 100%;
+ padding: 0.375rem; /* 6px => 0.375rem */
+ margin-top: 0.375rem; /* 6px => 0.375rem */
+ font-size: 0.75rem; /* 12px => 0.75rem */
+ }
+
+ .form-section h2 {
+ font-size: 1rem; /* 16px => 1rem */
+ }
+}
+@media (max-width: 320px) {
+ .login-outer-container {
+ padding-top: 0.5vh; /* Even smaller top padding for very small screens */
+ }
+
+ .login-container {
+ padding: 0.25rem;
+ }
+}
\ No newline at end of file
diff --git a/src/assets/badge1.png b/src/assets/badge1.png
new file mode 100644
index 0000000..75b568a
Binary files /dev/null and b/src/assets/badge1.png differ
diff --git a/src/assets/badge2.png b/src/assets/badge2.png
new file mode 100644
index 0000000..615fad2
Binary files /dev/null and b/src/assets/badge2.png differ
diff --git a/src/assets/badge3.png b/src/assets/badge3.png
new file mode 100644
index 0000000..fd6a4a1
Binary files /dev/null and b/src/assets/badge3.png differ
diff --git a/src/assets/ccs-bulb.png b/src/assets/ccs-bulb.png
new file mode 100644
index 0000000..4f907f3
Binary files /dev/null and b/src/assets/ccs-bulb.png differ
diff --git a/client/src/assets/ccs_logo.png b/src/assets/ccs_logo.png
similarity index 100%
rename from client/src/assets/ccs_logo.png
rename to src/assets/ccs_logo.png
diff --git a/src/assets/default_file.svg b/src/assets/default_file.svg
new file mode 100644
index 0000000..f297289
--- /dev/null
+++ b/src/assets/default_file.svg
@@ -0,0 +1,42 @@
+
+
+
diff --git a/src/assets/first1.png b/src/assets/first1.png
new file mode 100644
index 0000000..eb4d590
Binary files /dev/null and b/src/assets/first1.png differ
diff --git a/src/assets/second2.png b/src/assets/second2.png
new file mode 100644
index 0000000..8d1f10b
Binary files /dev/null and b/src/assets/second2.png differ
diff --git a/src/assets/third3.png b/src/assets/third3.png
new file mode 100644
index 0000000..e7c2c20
Binary files /dev/null and b/src/assets/third3.png differ
diff --git a/src/config.js b/src/config.js
new file mode 100644
index 0000000..888a433
--- /dev/null
+++ b/src/config.js
@@ -0,0 +1,3 @@
+const SERVER_URL = "https://api.codeboard.ccstiet.com/";
+// const SERVER_URL = "https://api.knowishan.fun/";
+export default SERVER_URL;
\ No newline at end of file
diff --git a/client/src/index.js b/src/index.js
similarity index 100%
rename from client/src/index.js
rename to src/index.js
diff --git a/client/src/rules.md b/src/rules.md
similarity index 100%
rename from client/src/rules.md
rename to src/rules.md
diff --git a/src/usernameform.css b/src/usernameform.css
new file mode 100644
index 0000000..f26126d
--- /dev/null
+++ b/src/usernameform.css
@@ -0,0 +1,402 @@
+/* Root Variables */
+:root {
+ --cont-color: rgb(18, 17, 17); /* Dark background for containers */
+ --ac-color: rgba(62, 216, 219, 0.866); /* Accent color for labels and headings */
+ --text-color: #ffffff; /* White text color */
+ --input-focus-color: rgb(77, 77, 77);
+}
+
+/* Global Reset */
+* {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ font-family: Arial, sans-serif;
+}
+html, body {
+ margin: 0;
+ padding: 0;
+}
+
+/* Body Styles */
+body {
+ background-color: #000000; /* Black background for the body */
+ color: var(--text-color); /* White text color */
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+ padding: 0;
+ margin: 0;
+}
+
+/* Container Styles */
+.username-entry-outer-container {
+ display: flex;
+ justify-content: center;
+ align-items: flex-start;
+ min-height: 100vh;
+ padding-top: 0.125vh;
+ padding: 0;
+ margin: 0;
+}
+
+.container {
+ background-color: var(--cont-color);
+ border-radius: 8px;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+ padding: 20px;
+ max-width: 1000px;
+ width: 100%;
+ text-align: center;
+ display: flex;
+ justify-content: space-evenly;
+ align-items: stretch;
+ flex-wrap: wrap;
+
+ margin: 0;
+}
+/* Left Column Styles */
+.left {
+ display: flex;
+ flex-direction: column;
+ width: 45%;
+
+ border-radius: 8px 0 0 8px;
+ align-items: center;
+ gap: 30px;
+ background: var(--cont-color);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ padding: 12px;
+}
+
+.left-top {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ width: 100%;
+ margin-top: 30px;
+ gap: 15px;
+ text-align: center;
+}
+
+.left-top h1 {
+ font-size: 32px;
+ color: var(--ac-color);
+ margin: 0;
+ font-weight: 700;
+}
+
+.left-top h2 {
+ font-size: 16px;
+ color: white;
+ font-weight: 500;
+}
+
+.left-bottom {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+
+ width: 100%;
+}
+
+.left-bottom h4 {
+ font-size: 20px;
+ color: var(--ac-color);
+
+ font-weight: 600;
+}
+
+.logo img {
+ width: 5rem;
+ border-radius: 50%;
+}
+
+.left-bottom .content {
+ display: flex;
+ align-items: center;
+ margin: 0.5rem;
+ padding: 0.4rem;
+}
+
+.profile {
+ width: 60px;
+ height: 60px;
+ margin-right: 10px; /* Adjust margin as needed */
+}
+
+.content-left {
+ flex: 1; /* Take up remaining space */
+
+}
+
+/* Adjustments for smaller screens */
+@media (max-width: 768px) {
+ .left {
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+ }
+
+ .content {
+ flex-direction: column;
+ align-items: center;
+ }
+
+ .profile {
+ margin-bottom: 10px; /* Adjust margin for spacing */
+ }
+}
+/* Right Column Styles */
+.right {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 15px;
+ margin-left: 8px;
+ width: 50%;
+ margin-bottom: 8px;
+}
+
+/* Form Styles */
+.user-form {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ width: 100%;
+ height: 100%;
+ justify-content: space-between;
+}
+
+.input-group-row {
+ display: flex;
+ gap: 15px;
+}
+
+.input-group {
+ position: relative;
+ margin-top: 10px;
+ height: 56px;
+}
+
+.input-group input,
+.input-group select {
+ width: 100%;
+ height: 100%;
+ padding: 0 10px;
+ border: 1px solid var(--ac-color);
+ border-radius: 4px;
+ font-size: 14px;
+ line-height: 56px;
+ background-color: var(--cont-color);
+ color: var(--text-color); /* White text color */
+}
+.input-group #roll-number,
+.input-group #email{
+ color: rgb(179, 179, 179);
+}
+
+.input-group label {
+ position: absolute;
+ top: 0;
+ left: 0;
+ font-size: 12px;
+ color: var(--ac-color);
+ transform: translateY(-50%) scale(0.75) translateX(-5%);
+ background: var(--cont-color);
+ pointer-events: none;
+ transition: none;
+}
+
+.input-group input:focus ~ label,
+.input-group input:not(:placeholder-shown) ~ label,
+.input-group select:focus ~ label,
+.input-group select:not([value=""]) ~ label {
+ top: 0;
+}
+
+.input-group select {
+ appearance: none;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='%235f6368' viewBox='0 0 16 16'%3E%3Cpath d='M7.247 11.14L2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z'/%3E%3C/svg%3E");
+ background-repeat: no-repeat;
+ background-position: right 10px center;
+ padding-right: 40px;
+}
+.input-group input:focus {
+ background-color: var(--cont-color); /* Dark background */
+ color: var(--text-color); /* White text */
+ border-color: var(--ac-color); /* Accent color border */
+}
+
+/* Optional: Style for when the input is not empty */
+.input-group input:not(:placeholder-shown) {
+ background-color: var(--cont-color); /* Dark background */
+ color: var(--text-color); /* White text */
+}
+.input-group select option[disabled] {
+ display: none;
+}
+
+.input-group select:invalid {
+ color: #5f6368;
+}
+
+/* Policy Styles */
+.policy {
+ display: flex;
+ align-items: center;
+}
+
+.policy label {
+ font-size: 14px;
+ color: #5f6368;
+ display: flex;
+ align-items: center;
+}
+
+.policy input[type="checkbox"] {
+ width: auto;
+ margin-right: 10px;
+}
+
+/* Button Styles */
+button {
+ background-color: var(--ac-color);
+ color: #ffffff;
+ padding: 10px;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 16px;
+}
+
+button:hover {
+ background-color: #139ad6;
+}
+
+/* Media Queries */
+@media (max-width: 768px) {
+
+ .container {
+ margin-top: 6rem;
+ flex-direction: column;
+ }
+
+ .left,
+ .right {
+ width: 100%;
+ margin: 0;
+ }
+}
+
+@media (max-width: 576px) {
+ .container {
+ box-shadow: none;
+ }
+
+ .left {
+
+ box-shadow: none;
+ }
+
+ .left-top h1 {
+ font-size: 24px;
+ }
+
+ .left-top h2 {
+ font-size: 14px;
+ }
+
+ .left-bottom h4 {
+ font-size: 18px;
+ }
+
+ .content p {
+ font-size: 14px;
+ }
+
+ .input-group label {
+ top: 0;
+ }
+
+ .input-group {
+ height: 45px;
+ }
+
+ .input-group input,
+ .input-group select {
+ width: 100%;
+ height: 40px;
+ padding: 0 10px;
+ border: 1px solid #39b9bc;
+ border-radius: 4px;
+ font-size: 14px;
+ line-height: 1.5;
+ background-color: var(--cont-color);
+ }
+
+ .policy label {
+ font-size: 12px;
+ }
+
+ button {
+ padding: 12px;
+ font-size: 16px;
+ }
+
+ .input-group label {
+ font-size: 12px;
+ }
+
+ .input-group input:focus ~ label,
+ .input-group input:not(:placeholder-shown) ~ label,
+ .input-group select:focus ~ label,
+ .input-group select:not([value=""]):not([value="Select your branch"]) ~ label {
+ font-size: 10px;
+ }
+}
+
+@media (max-width: 480px) {
+ .input-group-row {
+ flex-direction: column;
+ }
+
+ .input-group-row .input-group {
+ width: 100%;
+ }
+}
+@media (max-width: 600px) {
+ body{
+ background-color: rgb(18, 17, 17);
+ }
+}
+@media (max-width: 445px) {
+ .username-entry-outer-container {
+ align-items: flex-start;
+ padding-top: 0.125vh;
+ }
+ .container {
+
+ margin-bottom: 0.25rem;
+ margin-left: auto;
+ margin-right: auto;
+ flex-direction: column;
+ width: 98%; /* Increase width slightly */
+ max-width: 100%; /* Ensure it doesn't exceed screen width */
+ padding: 10px;
+ }
+}
+@media (max-width: 320px), (max-height: 600px) {
+ .username-entry-outer-container {
+ padding-top: 0.25rem; /* Reduced from 0.25vh to 0.125vh */
+ }
+ .container {
+ margin-top: 0rem;
+ margin-bottom: 0.25rem;
+ width: 98%;
+ padding-top: 0.25rem;
+ }
+}
\ No newline at end of file