From 12adfeaebc7ab651ccb3ad02eb9fb512cc6b940b Mon Sep 17 00:00:00 2001 From: Sawan Date: Tue, 5 Nov 2024 18:56:16 +0530 Subject: [PATCH 01/34] Share you blog on social media --- client/src/component/Blog.jsx | 153 +++++++++++++++++++--------------- 1 file changed, 85 insertions(+), 68 deletions(-) diff --git a/client/src/component/Blog.jsx b/client/src/component/Blog.jsx index b4061f9..2806771 100644 --- a/client/src/component/Blog.jsx +++ b/client/src/component/Blog.jsx @@ -43,16 +43,16 @@ export default function BlogPage(props) { return matchesSearch && matchesCategory; }); - const formatDate = (dateString) => { - const date = new Date(dateString); - if (isNaN(date.getTime())) { - throw new Error("Invalid date format"); - } - const day = String(date.getDate()).padStart(2, "0"); - const month = String(date.getMonth() + 1).padStart(2, "0"); - const year = date.getFullYear(); - return `${day}-${month}-${year}`; - }; + // const formatDate = (dateString) => { + // const date = new Date(dateString); + // if (isNaN(date.getTime())) { + // throw new Error("Invalid date format"); + // } + // const day = String(date.getDate()).padStart(2, "0"); + // const month = String(date.getMonth() + 1).padStart(2, "0"); + // const year = date.getFullYear(); + // return `${day}-${month}-${year}`; + // }; const categoryImage = (cat) => { const imgSrc = images.find((image) => image.category === cat); @@ -160,70 +160,87 @@ export default function BlogPage(props) { {/* Blog Grid */}
{filteredPosts.length > 0 ? ( - filteredPosts.map((blogPost) => ( - -
- {blogPost.title} { e.target.onerror = null; e.target.src = '/placeholder.svg'; }} - /> -
-

{blogPost.title}

-
- - -
- - - - - - - - {blogPost.category} + filteredPosts.map((blogPost) => { + const postUrl = `http://localhost:5000/api/blog/getById/${blogPost._id}`; + return ( +
+ {blogPost.title} { e.target.onerror = null; e.target.src = '/placeholder.svg'; }} + /> +
+

+ {blogPost.title} +

+
+
+ + + + + + + + {blogPost.category} +
+
+ + +
- -
-
+ - -
- {blogPost.content.replace(/<[^>]+>/g, '')}
-
- - - - - Read More - -
-
- - - )) + ); + }) ) : (
From 82117152bac2caa9ec9a98534f803bcf489d1f86 Mon Sep 17 00:00:00 2001 From: Ayush Date: Tue, 5 Nov 2024 21:14:39 +0530 Subject: [PATCH 02/34] faq visible in dark mode --- client/src/App.jsx | 2 +- client/src/component/About.jsx | 401 +++++++++++++++++++++++++++------ client/src/component/Faq.jsx | 20 +- 3 files changed, 339 insertions(+), 84 deletions(-) diff --git a/client/src/App.jsx b/client/src/App.jsx index 67e6e81..84eb74e 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -257,7 +257,7 @@ function App() { } /> } /> } /> - } /> {/* Add this line */} + } /> {/* Add this line */} } /> {/* Add this line */} } /> {/* Add this line */} } /> diff --git a/client/src/component/About.jsx b/client/src/component/About.jsx index 5daa715..a603541 100644 --- a/client/src/component/About.jsx +++ b/client/src/component/About.jsx @@ -1,14 +1,14 @@ import "../css/About.css"; -import PropTypes from 'prop-types'; +import PropTypes from "prop-types"; // import { useEffect } from "react"; import img1 from "../assets/images/Anuj.png"; import img2 from "../assets/images/Jitendra.png"; import img3 from "../assets/images/Harshit.png"; import AboutImgHero from "../assets/images/Others/heroimg.png"; -import '@fortawesome/fontawesome-free/css/all.css'; -import { faCoffee } from '@fortawesome/free-solid-svg-icons'; -import { faUser } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import "@fortawesome/fontawesome-free/css/all.css"; +import { faCoffee } from "@fortawesome/free-solid-svg-icons"; +import { faUser } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; // import {Contri} from './Contributers' // import { Link } from "react-router-dom"; @@ -50,17 +50,18 @@ export default function About(props) { About Us

- Bitbox is like a friendly community where people working on projects - can come together. If you’re stuck or need advice, you can ask for help. - And if you know something, you can share your knowledge with others. - It’s all about supporting each other and building a helpful community. 🌟 + Bitbox is like a friendly community where people working on + projects can come together. If you’re stuck or need advice, you + can ask for help. And if you know something, you can share your + knowledge with others. It’s all about supporting each other and + building a helpful community. 🌟

- Welcome to our open-source platform, where innovation knows no bounds - and collaboration is key. Dive into our repository of code, where - creativity flourishes and solutions come to life. Join our vibrant - community of developers, enthusiasts, and visionaries as we build the - future together, one line at a time. + Welcome to our open-source platform, where innovation knows no + bounds and collaboration is key. Dive into our repository of code, + where creativity flourishes and solutions come to life. Join our + vibrant community of developers, enthusiasts, and visionaries as + we build the future together, one line at a time.

@@ -106,81 +107,233 @@ export default function About(props) {

-
Our Team
+
+ Our{" "} + + Team + +

{/* card 1 */} -
-
- Anuj Verma is a tech-savvy person who loves working with AI and building websites. He's gained experience through internships and projects, showing that he's ready to do great things in the tech world. +
+
+ Anuj Verma is a tech-savvy person who loves working + with AI and building websites. He's gained experience + through internships and projects, showing that he's ready + to do great things in the tech world.
-

+

Anuj Verma

-

+

BTech CSE AIML
3rd Year

{/* card 2 */} -
-
- Jitendra Kumar: Tech enthusiast skilled in web development and database management, showcasing expertise in projects like weather app and algorithm analyzer, poised for impactful contributions in the tech industry. +
+
+ Jitendra Kumar: Tech enthusiast skilled in web + development and database management, showcasing expertise in + projects like weather app and algorithm analyzer, poised for + impactful contributions in the tech industry.
-

+

Jitendra Kumar

-

+

BTech CSE AIML
3rd Year

{/* card 3 */} -
-
- Harshit Singh: Entry-level software engineer skilled in C, C++, Python, HTML, CSS, and JavaScript. Eager to leverage abilities in problem-solving and project development for organizational growth. +
+
+ Harshit Singh: Entry-level software engineer skilled in + C, C++, Python, HTML, CSS, and JavaScript. Eager to leverage + abilities in problem-solving and project development for + organizational growth.
-

+

Harshit Singh

-

+

BTech CSE AIML
3rd Year

@@ -194,47 +347,117 @@ export default function About(props) {
-

+

Visitors

-
+
- 876K+ + + 876K+ +

VisitorCount

-
+
-
+
{/* */}
- 876K+ -

Registrations

+ + 876K+ + +

+ Registrations +

-
+
- 876K+ + + 876K+ +

Participants

-
+
-
+
{/* */}
- 828K+ -

Total Projects

+ + 828K+ + +

+ Total Projects +

@@ -244,50 +467,79 @@ export default function About(props) {
{/* FAQ */}
-
-

- Frequently Asked Questions +

+ + Frequently Asked Questions +

-
+
{[ { - question: "Will a beginner, with absolutely no knowledge of GitHub, gain anything fruitful?", - answer: "Absolutely! This program is designed to guide beginners, with projects and support for all experience levels." + question: + "Will a beginner, with absolutely no knowledge of GitHub, gain anything fruitful?", + answer: + "Absolutely! This program is designed to guide beginners, with projects and support for all experience levels.", }, { question: "Are there any charges for registration?", - answer: "No, participating in this program is entirely free with no hidden costs." + answer: + "No, participating in this program is entirely free with no hidden costs.", }, { - question: "Is there a specific age requirement for participation?", - answer: "There are no age restrictions! People of all ages are welcome to join and contribute." + question: + "Is there a specific age requirement for participation?", + answer: + "There are no age restrictions! People of all ages are welcome to join and contribute.", }, { question: "What are the project requirements?", - answer: "Projects are open-ended, allowing mentors to share ideas in their fields of expertise without restrictions." + answer: + "Projects are open-ended, allowing mentors to share ideas in their fields of expertise without restrictions.", }, { - question: "As a beginner, where should we begin to contribute effectively to projects?", - answer: "The resources on our website, including GitHub links and tutorials, will help you contribute effectively." + question: + "As a beginner, where should we begin to contribute effectively to projects?", + answer: + "The resources on our website, including GitHub links and tutorials, will help you contribute effectively.", }, ].map((item, index) => (
-

+

))}
-
{/* Info */} {/*
@@ -297,10 +549,9 @@ export default function About(props) { ); } - // Props Validation About.propTypes = { mode: PropTypes.string, toggleMode: PropTypes.func, showAlert: PropTypes.func, -}; \ No newline at end of file +}; diff --git a/client/src/component/Faq.jsx b/client/src/component/Faq.jsx index 15e299f..541d836 100644 --- a/client/src/component/Faq.jsx +++ b/client/src/component/Faq.jsx @@ -1,6 +1,6 @@ // component/FAQ.jsx -import { useState } from 'react'; -import '../css/Faq.css'; +import { useState } from "react"; +import "../css/Faq.css"; const FAQ = () => { const [activeIndex, setActiveIndex] = useState(null); @@ -27,25 +27,29 @@ const FAQ = () => { const faqData = [ { question: "What is BitBox?", - answer: "BitBox is a user-friendly platform that simplifies version control and collaboration for developers.", + answer: + "BitBox is a user-friendly platform that simplifies version control and collaboration for developers.", }, { question: "How does BitBox enhance collaboration?", - answer: "BitBox offers intuitive tools that enable both solo programmers and large teams to manage projects efficiently.", + answer: + "BitBox offers intuitive tools that enable both solo programmers and large teams to manage projects efficiently.", }, { question: "How do I get started with BitBox?", - answer: "You can sign up for an account on BitBox and start managing your projects right away.", + answer: + "You can sign up for an account on BitBox and start managing your projects right away.", }, { question: "Is BitBox compatible with modern development workflows?", - answer: "Yes, BitBox seamlessly integrates with modern development workflows, providing fast and reliable performance.", + answer: + "Yes, BitBox seamlessly integrates with modern development workflows, providing fast and reliable performance.", }, { question: "How can I contact support if I need help?", - answer: "You can reach out to support through the 'Contact Us' page or by emailing support@example.com.", + answer: + "You can reach out to support through the 'Contact Us' page or by emailing support@example.com.", }, ]; - export default FAQ; From 6364b225af36a089f3e5f4c3b5041664ae0d74aa Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Nov 2024 21:44:21 +0530 Subject: [PATCH 03/34] feedback --- client/src/App.jsx | 18 +++++- client/src/FeedbackForm.css | 91 +++++++++++++++++++++++++++++++ client/src/component/Feedback.jsx | 73 +++++++++++++++++++++++++ 3 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 client/src/FeedbackForm.css create mode 100644 client/src/component/Feedback.jsx diff --git a/client/src/App.jsx b/client/src/App.jsx index 67e6e81..8b1c669 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -29,6 +29,7 @@ import Contributors from "./component/Contributors"; import Discussion from "./component/Discussion"; import ForgotPassword from "./component/ForgotPassword"; import ResetPassword from "./component/ResetPassword"; +import Feedback from "./component/Feedback"; // import VerifyEmail from "./component/Verify"; // import ProtectedRoute from '../../client/src/component/ProtectedRoute' import NotFound from "./component/NotFound"; @@ -58,6 +59,7 @@ const Layout = ({ children, mode, setProgress, toggleMode, showAlert }) => { blog="Blogs" discussion="Discussion" contributors="Contributors" + Feedback="Feedback" showAlert={showAlert} mode={mode} toggleMode={toggleMode} @@ -131,6 +133,9 @@ function App() { progress={progress} onLoaderFinished={() => setProgress(0)} /> +
+ +
@@ -199,6 +204,17 @@ function App() { /> } /> + + } + /> } /> } /> } /> - } /> + } /> } /> } /> } /> diff --git a/client/src/FeedbackForm.css b/client/src/FeedbackForm.css new file mode 100644 index 0000000..6bab1f5 --- /dev/null +++ b/client/src/FeedbackForm.css @@ -0,0 +1,91 @@ +.feedback-container { + max-width: 400px; + margin: 2rem auto; + padding: 2rem; + background-color: #1e1e1e; + border-radius: 8px; + box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.3); + color: #f0f0f0; + text-align: center; + } + + .feedback-container h2 { + margin-bottom: 1.5rem; + color: #e0e0e0; + } + + .feedback-form { + display: flex; + flex-direction: column; + } + + .feedback-form input, + .feedback-form textarea { + margin-bottom: 1rem; + padding: 0.8rem; + border: 1px solid #444; + border-radius: 4px; + background-color: #2e2e2e; + color: #f0f0f0; + } + + .feedback-form input::placeholder, + .feedback-form textarea::placeholder { + color: #a0a0a0; + } + + .feedback-form textarea { + resize: none; + height: 100px; + } + + .rating { + display: flex; + align-items: center; + margin-bottom: 1rem; + } + + .rating p { + margin: 0; + margin-right: 0.5rem; + color: #e0e0e0; + } + + .star { + font-size: 1.5rem; + color: #ccc; + cursor: pointer; + transition: color 0.3s ease; + } + + /* Filled stars - Gold when hovered or selected */ + .star.filled { + color: #ffb400; + } + + /* Additional hover effect: Make all stars up to the hovered one gold */ + .star:hover, + .star:hover ~ .star { + color: #ccc; + } + + .star:hover, + .star:hover ~ .star { + color: #ffb400; + } + + .feedback-form button { + padding: 0.8rem; + border: none; + border-radius: 4px; + background-color: #ff6347; + color: #fff; + font-weight: bold; + cursor: pointer; + transition: background-color 0.3s ease; + } + + .feedback-form button:hover { + background-color: #ff4500; + } + \ No newline at end of file diff --git a/client/src/component/Feedback.jsx b/client/src/component/Feedback.jsx new file mode 100644 index 0000000..a6a9411 --- /dev/null +++ b/client/src/component/Feedback.jsx @@ -0,0 +1,73 @@ +import React, { useState } from "react"; +import "./client/src/FeedbackForm.css"; + +const FeedbackForm = () => { + const [rating, setRating] = useState(0); + const [hoverRating, setHoverRating] = useState(0); + const [formData, setFormData] = useState({ + name: "", + email: "", + feedback: "", + }); + + const handleInputChange = (e) => { + const { name, value } = e.target; + setFormData((prev) => ({ ...prev, [name]: value })); + }; + + const handleSubmit = (e) => { + e.preventDefault(); + console.log("Feedback Submitted:", formData, "Rating:", rating); + // Add submission logic here + }; + + return ( +
+

Give Us Your Feedback

+
+ + + +
+ + {/* GitHub Link */} +
+ + +
+ + {/* Deployment Link */} +
+ + +
+ + + + {/* Submit Button */}
-
-
{props.title} 👇
- -
+
-
+
- ) -} + ); +}; -// Props Vadilation UploadProject.propTypes = { - title: PropTypes.string, - desc: PropTypes.string, - showAlert: PropTypes.func, + + mode: PropTypes.string, + }; -export default UploadProject \ No newline at end of file +export default UploadProject; diff --git a/server/Controllers/projectController.js b/server/Controllers/projectController.js new file mode 100644 index 0000000..fda139f --- /dev/null +++ b/server/Controllers/projectController.js @@ -0,0 +1,33 @@ +const Project = require('../Models/ProjectSchema.js'); + +exports.postProject = async (req, res) => { + const { title, description, githubLink, deploymentLink } = req.body; + + if (!title || !description) { + return res.status(400).json({ message: 'Title and description are required' }); + } + + try { + const newProject = new Project({ + title, + description, + githubLink, + deploymentLink, + }); + + await newProject.save(); + + return res.status(201).json({ message: 'Project created successfully', project: newProject }); + } catch (error) { + return res.status(500).json({ message: 'Error creating project', error }); + } +}; + +exports.getAllProjects = async (req, res) => { + try { + const projects = await Project.find(); + return res.status(200).json(projects); + } catch (error) { + return res.status(500).json({ message: 'Error fetching projects', error }); + } +}; diff --git a/server/Models/ProjectSchema.js b/server/Models/ProjectSchema.js new file mode 100644 index 0000000..61c0107 --- /dev/null +++ b/server/Models/ProjectSchema.js @@ -0,0 +1,12 @@ +const mongoose = require('mongoose'); + +const projectSchema = new mongoose.Schema({ + title: { type: String, required: true }, + description: { type: String, required: true }, + githubLink: { type: String }, + deploymentLink: { type: String }, +}); + +const Project = mongoose.model('Project', projectSchema); + +module.exports = Project; diff --git a/server/index.js b/server/index.js index 4fbf7f8..dea3894 100644 --- a/server/index.js +++ b/server/index.js @@ -48,6 +48,7 @@ app.use("/api/feedback", require("./routes/feedback")); app.use("/api/contact", require("./routes/contact")); app.use("/api/blog", require("./routes/blog")); app.use("/api/visitor", require("./routes/visitor")); +app.use("/api/showcaseProjects", require("./routes/projectsRoute")); // Socket.io connection handling const users = {}; diff --git a/server/routes/projects.js b/server/routes/projects.js index e422db1..d0f1794 100644 --- a/server/routes/projects.js +++ b/server/routes/projects.js @@ -3,14 +3,14 @@ const router = express.Router(); const Project = require('../Models/Project'); const fetchuser = require('../middleware/fetchuser'); const { validationResult, body } = require('express-validator'); // Add 'body' here -const { +const { fetchallglobalprojects, fetchalluserprojects, addproject, updateproject, deleteproject, uploadProjectImage, - getProjectImage + getProjectImage } = require('../Controllers/projects'); // ROUTE 1 : Get All Global Projects : GET: "/api/projects/fetchallglobalprojects". No Login required diff --git a/server/routes/projectsRoute.js b/server/routes/projectsRoute.js new file mode 100644 index 0000000..e411fc8 --- /dev/null +++ b/server/routes/projectsRoute.js @@ -0,0 +1,9 @@ +const express = require('express'); +const router = express.Router(); +const projectController = require('../Controllers/projectController.js'); + +router.post('/post-project', projectController.postProject); +router.get('/all-projects', projectController.getAllProjects); + + +module.exports = router; From 30ac6f044c110bebd8b81c8bce13536c16c00ed1 Mon Sep 17 00:00:00 2001 From: Sawan Date: Thu, 7 Nov 2024 12:39:54 +0530 Subject: [PATCH 18/34] Added search funcnality for both issues and contributors --- client/src/component/Contributors.jsx | 132 +++++++++++++++++--------- 1 file changed, 87 insertions(+), 45 deletions(-) diff --git a/client/src/component/Contributors.jsx b/client/src/component/Contributors.jsx index 84ffb66..6f5a62b 100644 --- a/client/src/component/Contributors.jsx +++ b/client/src/component/Contributors.jsx @@ -223,20 +223,21 @@ StatCard.propTypes = { onClick: PropTypes.func, }; + export default function Contributor(props) { const [contributors, setContributors] = useState([]); const [openIssues, setOpenIssues] = useState([]); const [showIssue, setShowIssue] = useState(true); // Determine which section to show const [loading, setLoading] = useState(true); const [currentPage, setCurrentPage] = useState(1); - const itemsPerPage = 9; // Set the number of items per page (for both contributors and issues) - const [repoStats, setRepoStats] = useState({ stars: 0, forks: 0, openIssues: 0, }); + const [searchTerm, setSearchTerm] = useState(''); // State for search term + const itemsPerPage = 9; // Set the number of items per page (for both contributors and issues) useEffect(() => { const fetchData = async () => { @@ -250,10 +251,8 @@ export default function Contributor(props) { const contributorsData = await contributorsResponse.json(); setContributors(contributorsData); - // Fetch repo stats const repoResponse = await fetch('https://api.github.com/repos/Bitbox-Connect/Bitbox'); - const repoData = await repoResponse.json(); setRepoStats({ stars: repoData.stargazers_count, @@ -279,15 +278,27 @@ export default function Contributor(props) { const indexOfLastItem = currentPage * itemsPerPage; const indexOfFirstItem = indexOfLastItem - itemsPerPage; - // Get current items based on selected section - const currentItems = showIssue ? openIssues.slice(indexOfFirstItem, indexOfLastItem) : contributors.slice(indexOfFirstItem, indexOfLastItem); + // Filter contributors or issues based on search term + const filteredContributors = contributors.filter(contributor => + contributor.login.toLowerCase().includes(searchTerm.toLowerCase()) + ); + + const filteredIssues = openIssues.filter(issue => + issue.title.toLowerCase().includes(searchTerm.toLowerCase()) + ); + + // Get current items based on selected section and search + const currentItems = showIssue + ? filteredIssues.slice(indexOfFirstItem, indexOfLastItem) + : filteredContributors.slice(indexOfFirstItem, indexOfLastItem); // Determine total pages - const totalPages = showIssue ? Math.ceil(openIssues.length / itemsPerPage) : Math.ceil(contributors.length / itemsPerPage); + const totalPages = showIssue + ? Math.ceil(filteredIssues.length / itemsPerPage) + : Math.ceil(filteredContributors.length / itemsPerPage); const paginate = (pageNumber) => setCurrentPage(pageNumber); - return (
- {/* Repository Stars */} + {/* Repository Stats */} - {/* Repository Forks */} - + {/* Forks */} + + } /> - {/* Open Issues */}
-
+ {/* Search Section */} +
-

{showIssue ? 'Your contribution is valuable see all Issues' : 'Contributors'}

-
- {currentItems.map(item => showIssue ? ( - + setSearchTerm(e.target.value)} + /> +
+
+ + {/* Display Issues or Contributors based on `showIssue` */} +
+
+
+ {currentItems.length > 0 ? ( + currentItems.map(item => ( + showIssue ? ( + + ) : ( + + ) + )) ) : ( - - ))} +
No items found
+ )}
-
- {Array.from({ length: totalPages }, (_, i) => ( +
+
+ + {/* Pagination */} +
+
+
+ {Array.from({ length: totalPages }).map((_, index) => ( ))}
-
- - +
); } + +Contributor.propTypes = { + mode: PropTypes.string.isRequired, +}; \ No newline at end of file From 10b43c10fcee083cdfa8084a5a9bd9f21ffd726d Mon Sep 17 00:00:00 2001 From: Ikki Date: Thu, 7 Nov 2024 13:22:06 +0530 Subject: [PATCH 19/34] handled-errors-login --- client/src/component/Login.jsx | 43 ++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/client/src/component/Login.jsx b/client/src/component/Login.jsx index aa29cbc..99f9569 100644 --- a/client/src/component/Login.jsx +++ b/client/src/component/Login.jsx @@ -31,6 +31,13 @@ const Login = ({ mode, isloggedin, setloggedin }) => { // Handle form submission for login const handleSubmit = async (e) => { e.preventDefault(); + + // Check for empty fields + if (!credentials.email || !credentials.password) { + toast.error("Please enter both email and password."); + return; + } + setLoading(true); try { const response = await fetch(`${VITE_SERVER_PORT}/api/auth/login`, { @@ -40,18 +47,33 @@ const Login = ({ mode, isloggedin, setloggedin }) => { }, body: JSON.stringify(credentials), }); + + if (!response.ok) { + // Check for network or server errors + if (response.status === 500) { + toast.error("Server error. Please try again later."); + } else { + toast.error("Login failed! Please check your credentials."); + } + throw new Error("Response not ok"); + } + const json = await response.json(); if (json.success) { localStorage.setItem("token", json.authtoken); - toast.success("Login Successfully!"); + toast.success("Login successful!"); setloggedin(!isloggedin); navigate("/"); } else { - toast.error("Login failed!"); + toast.error(json.message || "Login failed! Invalid credentials."); } } catch (error) { - toast.error("An error occurred. Please try again later."); + if (error.message === "NetworkError") { + toast.error("Network error. Please check your connection."); + } else { + toast.error("An unexpected error occurred. Please try again later."); + } console.error("Error during login:", error); } finally { setLoading(false); @@ -66,21 +88,28 @@ const Login = ({ mode, isloggedin, setloggedin }) => { // Remember email if "Remember Me" is checked const handleRememberMe = (e) => { if (e.target.checked) { - localStorage.setItem('rememberedEmail', credentials.email); + localStorage.setItem("rememberedEmail", credentials.email); } else { - localStorage.removeItem('rememberedEmail'); + localStorage.removeItem("rememberedEmail"); } }; + // Handle Google Sign-In const onGoogleSignIn = async (e) => { e.preventDefault(); try { const { token } = await doSignInWithGoogle(); - localStorage.setItem("token", token); - setloggedin(true); + if (token) { + localStorage.setItem("token", token); + setloggedin(true); + toast.success("Google sign-in successful!"); + } else { + toast.error("Google sign-in failed."); + } } catch (error) { console.error("Google sign-in error:", error); + toast.error("Google sign-in failed. Please try again."); setloggedin(false); } }; From e34739a3dc43ec1d59d5fdecc9d7382bdf8b32ce Mon Sep 17 00:00:00 2001 From: Ikki Date: Thu, 7 Nov 2024 14:10:54 +0530 Subject: [PATCH 20/34] signup-password-validation --- client/src/component/Signup.jsx | 98 +++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 36 deletions(-) diff --git a/client/src/component/Signup.jsx b/client/src/component/Signup.jsx index 0aa28d2..96a8879 100644 --- a/client/src/component/Signup.jsx +++ b/client/src/component/Signup.jsx @@ -23,32 +23,55 @@ const Signup = ({ mode }) => { // eslint-disable-next-line const [errors, setErrors] = useState({}); const [isLoggedIn, setLoggedIn] = useState(false); + const [requirements, setRequirements] = useState({ + length: false, + uppercase: false, + lowercase: false, + number: false, + specialChar: false, + }); + + const handlePasswordChange = (e) => { + const newPassword = e.target.value; + setPassword(newPassword); + + setRequirements({ + length: newPassword.length >= 8, + uppercase: /[A-Z]/.test(newPassword), + lowercase: /[a-z]/.test(newPassword), + number: /\d/.test(newPassword), + specialChar: /[@$!%*?&]/.test(newPassword), + }); + }; const handleSubmit = async (e) => { e.preventDefault(); - // try { - // // Validation not working - // await registerValidation.validate( - // { name, email, password, cpassword }, - // { abortEarly: false } - // ); - - // setErrors({}); - // } catch (error) { - // const newErrors = {}; - // error.inner.forEach((err) => { - // newErrors[err.path] = err.message; - // }); + // Check if the password meets the requirements + if (!Object.values(requirements).every(Boolean)) { + setErrors((prevErrors) => ({ + ...prevErrors, + password: "Password does not meet the required criteria.", + })); + return; + } else { + setErrors((prevErrors) => ({ ...prevErrors, password: null })); + } - // setErrors(newErrors); - // return; - // } + // Check if password and confirm password match + if (password !== cpassword) { + setErrors((prevErrors) => ({ + ...prevErrors, + cpassword: "Passwords do not match.", + })); + return; + } else { + setErrors((prevErrors) => ({ ...prevErrors, cpassword: null })); + } + // Reset form after submission setTimeout(() => { - e.target.reset(); // Reset the form after 1 second - setName(""); - setEmail(""); + e.target.reset(); setPassword(""); setCPassword(""); }, 1000); @@ -76,20 +99,7 @@ const Signup = ({ mode }) => { }, body: JSON.stringify({ name, email, password }), }); - document.querySelector('#login-btn').addEventListener('click', (event) => { - event.preventDefault(); - - const emailInput = document.getElementById('login-email'); - const rememberMeCheckbox = document.getElementById('login-remember'); - - if (rememberMeCheckbox.checked) { - localStorage.setItem('rememberedEmail', emailInput.value); - } else { - localStorage.removeItem('rememberedEmail'); - } - - // Continue with your existing login logic... - }); + const json = await response.json(); if (json.success) { @@ -100,7 +110,13 @@ const Signup = ({ mode }) => { toast.error(json.message || "An error occurred. Please try again later."); } }; - + const handleRememberMe = (e) => { + if (e.target.checked) { + localStorage.setItem('rememberedEmail', credentials.email); + } else { + localStorage.removeItem('rememberedEmail'); + } + }; return (
{userLoggedIn && navigate('/')} @@ -200,7 +216,7 @@ const Signup = ({ mode }) => { setPassword(e.target.value)} + onChange={handlePasswordChange} id="password" name="password" placeholder="Enter Your Password" @@ -216,6 +232,16 @@ const Signup = ({ mode }) => { } />
+
+

Password must contain:

+
    +
  • At least 8 characters
  • +
  • At least one uppercase letter
  • +
  • At least one lowercase letter
  • +
  • At least one number
  • +
  • At least one special character
  • +
+
@@ -497,95 +474,12 @@ function Navbar(props) {
  • - setIsSidebarOpen(false)}> + setIsSidebarOpen(false)}> {props.profile}
  • - - {localStorage.getItem("token") ? ( - <> - {/* Add Project */} -
  • {renderUploadButton()}
  • - - {/* User Profile */} - - {/* User DropDown Option */} - -
  • - - My Profile - -
  • -
  • - - Edit Profile - -
  • - -
  • - - Logout - -
  • - - ) : ( - <> -
  • - - Login - -
  • -
  • - - Signup - -
  • - - )}
    - - {/* Sidebar Toggle Button */} - < button - className="sidebar-toggle" - onClick={() => setIsSidebarOpen(true)} - style={{ display: isOpen ? "block" : "none" }} - > - Menu -
    ); diff --git a/client/src/component/UploadProject.jsx b/client/src/component/UploadProject.jsx index cd70f65..9455a3a 100644 --- a/client/src/component/UploadProject.jsx +++ b/client/src/component/UploadProject.jsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import { useState } from 'react'; import PropTypes from "prop-types"; import { useNavigate } from 'react-router-dom'; @@ -74,10 +74,10 @@ const UploadProject = ({ mode }) => { {/* Modal Overlay */} {isModalOpen && ( -
    +
    {/* Modal Content */}
    {/* Close Button in Top Right */} diff --git a/client/src/css/MyProfile.css b/client/src/css/MyProject.css similarity index 100% rename from client/src/css/MyProfile.css rename to client/src/css/MyProject.css diff --git a/client/src/css/Navbar.css b/client/src/css/Navbar.css index e27cb81..73fb3d6 100644 --- a/client/src/css/Navbar.css +++ b/client/src/css/Navbar.css @@ -458,31 +458,20 @@ cursor: pointer; margin: 15px; } -.mobile-dark-theme{ - position: fixed; - right: 80px; -} -.sidebar-toggle { - position: fixed; - right: 20px; +.sidebar-toggle { background-color: #007bff; color: white; border: none; padding: 10px; border-radius: 5px; - cursor: pointer; } @media (min-width: 1280px) { - .sidebar { display: none; /* Hide on larger screens */ } - .mobile-dark-theme{ - display: none; - } .sidebar-toggle { display: none; @@ -546,13 +535,16 @@ position: fixed; top: 0; left: 0; - width: 250px; /* Adjust as needed */ + width: 250px; + /* Adjust as needed */ height: 100vh; overflow-y: auto; transition: transform 0.3s ease-in-out; - transform: translateX(-100%); /* Initially hidden */ + transform: translateX(-100%); + /* Initially hidden */ z-index: 1000; - background-color: #111; /* Change color based on theme */ + background-color: #111; + /* Change color based on theme */ } .sidebar.open { @@ -564,4 +556,4 @@ /* Lock background scroll when sidebar is open */ .no-scroll { overflow: hidden; -} +} \ No newline at end of file From a683b29bdef48a5d5879dc68473c78f2ea866acb Mon Sep 17 00:00:00 2001 From: Anuj3553 Date: Fri, 8 Nov 2024 10:41:19 +0530 Subject: [PATCH 26/34] Refactor FAQ component and update Navbar styles for improved layout --- client/src/component/Navbar.jsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/client/src/component/Navbar.jsx b/client/src/component/Navbar.jsx index 236109e..456047e 100644 --- a/client/src/component/Navbar.jsx +++ b/client/src/component/Navbar.jsx @@ -243,10 +243,12 @@ function Navbar(props) {
    {localStorage.getItem("token") ? ( <> -
      -
      +
        +
        {/* Render Add Project */} - {renderUploadButton()} +
        + {renderUploadButton()} +
        {/* Dark Mode Toggle Button */}
      • @@ -475,7 +477,7 @@ function Navbar(props) {
      • setIsSidebarOpen(false)}> - {props.profile} + {props.projects}
      From c2698f1e30356a5e1c8940f3a4217cfa2c7f1a6a Mon Sep 17 00:00:00 2001 From: Anuj3553 Date: Fri, 8 Nov 2024 10:47:29 +0530 Subject: [PATCH 27/34] Remove FAQ component and related styles from the application --- client/src/App.jsx | 4 -- client/src/component/FAQ.jsx | 51 ------------- client/src/component/Faq.jsx | 49 ------------- client/src/component/Footer.jsx | 3 - client/src/component/Footers/FAQ.jsx | 21 ------ client/src/component/Footers/VisitorCount.jsx | 1 - client/src/css/Faq.css | 72 ------------------- 7 files changed, 201 deletions(-) delete mode 100644 client/src/component/FAQ.jsx delete mode 100644 client/src/component/Faq.jsx delete mode 100644 client/src/component/Footers/FAQ.jsx delete mode 100644 client/src/css/Faq.css diff --git a/client/src/App.jsx b/client/src/App.jsx index 7c7211c..5a69abf 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -30,14 +30,12 @@ import Discussion from "./component/Discussion"; import ForgotPassword from "./component/ForgotPassword"; import ResetPassword from "./component/ResetPassword"; import NotFound from "./component/NotFound"; -import Faq from "./component/Faq"; import ProgressBar from "./component/ProgressBar/ProgressBar"; import Cursor from './component/Cursor'; import ReadMoreBlog from './component/ReadMoreBlog'; import AOS from "aos"; import "aos/dist/aos.css"; import Collab from "./component/Collab"; -import FAQ from "./component/Faq"; import CreateBlog from "./component/CreateBlog"; import UploadProject from "./component/UploadProject"; @@ -134,7 +132,6 @@ function App() { } /> } /> } /> - } /> } /> } /> } /> @@ -147,7 +144,6 @@ function App() { } /> } /> } /> - } /> } /> } /> } /> diff --git a/client/src/component/FAQ.jsx b/client/src/component/FAQ.jsx deleted file mode 100644 index ae2e048..0000000 --- a/client/src/component/FAQ.jsx +++ /dev/null @@ -1,51 +0,0 @@ -// component/FAQ.jsx -import React, { useState } from 'react'; -import './FAQ.css'; // Import the CSS file for styling - -const FAQ = () => { - const [activeIndex, setActiveIndex] = useState(null); - - const toggleAnswer = (index) => { - setActiveIndex(activeIndex === index ? null : index); - }; - - return ( -
      -

      Frequently Asked Questions

      - {faqData.map((item, index) => ( -
      -

      toggleAnswer(index)} className="faq-question"> - {item.question} -

      - {activeIndex === index &&

      {item.answer}

      } -
      - ))} -
      - ); -}; - -const faqData = [ - { - question: "What is BitBox?", - answer: "BitBox is a user-friendly platform that simplifies version control and collaboration for developers.", - }, - { - question: "How does BitBox enhance collaboration?", - answer: "BitBox offers intuitive tools that enable both solo programmers and large teams to manage projects efficiently.", - }, - { - question: "How do I get started with BitBox?", - answer: "You can sign up for an account on BitBox and start managing your projects right away.", - }, - { - question: "Is BitBox compatible with modern development workflows?", - answer: "Yes, BitBox seamlessly integrates with modern development workflows, providing fast and reliable performance.", - }, - { - question: "How can I contact support if I need help?", - answer: "You can reach out to support through the 'Contact Us' page or by emailing support@example.com.", - }, -]; - - -export default FAQ; diff --git a/client/src/component/Faq.jsx b/client/src/component/Faq.jsx deleted file mode 100644 index b2f2da9..0000000 --- a/client/src/component/Faq.jsx +++ /dev/null @@ -1,49 +0,0 @@ -// component/FAQ.jsx -import { useState } from 'react'; -import '../css/Faq.css'; - -export default function FAQ() { - const [activeIndex, setActiveIndex] = useState(null); - - const toggleAnswer = (index) => { - setActiveIndex(activeIndex === index ? null : index); - }; - - const faqData = [ - { - question: "What is BitBox?", - answer: "BitBox is a user-friendly platform that simplifies version control and collaboration for developers.", - }, - { - question: "How does BitBox enhance collaboration?", - answer: "BitBox offers intuitive tools that enable both solo programmers and large teams to manage projects efficiently.", - }, - { - question: "How do I get started with BitBox?", - answer: "You can sign up for an account on BitBox and start managing your projects right away.", - }, - { - question: "Is BitBox compatible with modern development workflows?", - answer: "Yes, BitBox seamlessly integrates with modern development workflows, providing fast and reliable performance.", - }, - { - question: "How can I contact support if I need help?", - answer: "You can reach out to support through the 'Contact Us' page or by emailing support@example.com.", - }, - ]; - - return ( -
      -

      Frequently Asked Questions

      - {faqData.map((item, index) => ( -
      -

      toggleAnswer(index)} className="faq-question"> - {item.question} -

      - {activeIndex === index &&

      {item.answer}

      } -
      - ))} -
      - ); -} - diff --git a/client/src/component/Footer.jsx b/client/src/component/Footer.jsx index 970ca5a..b5e151b 100644 --- a/client/src/component/Footer.jsx +++ b/client/src/component/Footer.jsx @@ -209,9 +209,6 @@ const Footer = (props) => {
    • Blog
    • -
    • - FAQ -
    diff --git a/client/src/component/Footers/FAQ.jsx b/client/src/component/Footers/FAQ.jsx deleted file mode 100644 index 3480626..0000000 --- a/client/src/component/Footers/FAQ.jsx +++ /dev/null @@ -1,21 +0,0 @@ -// component/FAQ.jsx -import React from 'react'; - -const FAQ = () => { - return ( -
    -

    Frequently Asked Questions

    -
    -

    Question 1: What is this project about?

    -

    Answer: This project is designed to help users...

    -
    -
    -

    Question 2: How do I get started?

    -

    Answer: To get started, you can...

    -
    - {/* Add more FAQ items as needed */} -
    - ); -}; - -export default FAQ; diff --git a/client/src/component/Footers/VisitorCount.jsx b/client/src/component/Footers/VisitorCount.jsx index aafadde..bcedca6 100644 --- a/client/src/component/Footers/VisitorCount.jsx +++ b/client/src/component/Footers/VisitorCount.jsx @@ -7,7 +7,6 @@ async function incrementVisitorCount() { method: "POST", }); const data = await response.json(); - console.log("Visitor count incremented:", data.count); return data.count; } catch (error) { console.error("Error incrementing visitor count:", error); diff --git a/client/src/css/Faq.css b/client/src/css/Faq.css deleted file mode 100644 index 0e92737..0000000 --- a/client/src/css/Faq.css +++ /dev/null @@ -1,72 +0,0 @@ -.faq-container { - max-width: 700px; - margin: 40px auto; - padding: 30px; - background-color: #ffffff; - border-radius: 12px; - box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); - } - - h2 { - margin-top: 60px; - text-align: center; - color: #333; - margin-bottom: 30px; - font-size: 2rem; - font-family: 'Arial', sans-serif; - } - - .faq-list { - display: flex; - flex-direction: column; - gap: 15px; - } - - .faq-card { - background-color: #f7f7f7; - border-radius: 8px; - padding: 15px 20px; - transition: background-color 0.3s ease, transform 0.3s ease; - border-left: 4px solid #01356d; - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); - } - .view-more { - margin-top: 1rem; - padding: 10px 20px; - background-color: #003064; /* Bootstrap primary color */ - color: white; - border: none; - border-radius: 5px; - cursor: pointer; - transition: background-color 0.3s; - - } - - .view-more:hover { - background-color: #054486; /* Darker shade on hover */ - } - - .faq-card:hover { - background-color: #f5faff; - transform: translateY(-3px); - } - - .faq-question { - cursor: pointer; - font-size: 1.1em; - color: #003a77; - margin: 0; - font-family: 'Arial', sans-serif; - } - - .faq-question:hover { - color: #0056b3; - } - - .faq-answer { - margin-top: 10px; - font-size: 0.95em; - color: #555; - line-height: 1.6; - } - \ No newline at end of file From 86cb821863e1dda9c86d214168e3f1bc82e7790b Mon Sep 17 00:00:00 2001 From: Anuj3553 Date: Fri, 8 Nov 2024 10:59:43 +0530 Subject: [PATCH 28/34] Refactor Privacy Policy and Terms of Use components for improved styling and layout --- .../src/component/Footers/Privacypolicy.jsx | 12 ++++++---- client/src/component/Footers/TermOfUse.jsx | 23 +++++++++---------- client/src/css/Main.css | 11 --------- 3 files changed, 18 insertions(+), 28 deletions(-) diff --git a/client/src/component/Footers/Privacypolicy.jsx b/client/src/component/Footers/Privacypolicy.jsx index 8162943..50237bb 100644 --- a/client/src/component/Footers/Privacypolicy.jsx +++ b/client/src/component/Footers/Privacypolicy.jsx @@ -1,12 +1,12 @@ import '../../css/Main.css'; import PropTypes from 'prop-types'; -export default function PrivacyPolicy() { +export default function PrivacyPolicy(props) { const VITE_CLIENT_PORT = import.meta.env.VITE_CLIENT_PORT; return ( -
    -

    +

    Privacy Policy

    @@ -154,7 +154,7 @@ export default function PrivacyPolicy() {
    - +
    @@ -163,4 +163,6 @@ export default function PrivacyPolicy() { PrivacyPolicy.propTypes = { VITE_CLIENT_PORT: PropTypes.string, + mode: PropTypes.string, + props: PropTypes.object, }; diff --git a/client/src/component/Footers/TermOfUse.jsx b/client/src/component/Footers/TermOfUse.jsx index 12829ee..2e0ebab 100644 --- a/client/src/component/Footers/TermOfUse.jsx +++ b/client/src/component/Footers/TermOfUse.jsx @@ -2,11 +2,10 @@ import '../../css/Main.css'; import PropTypes from 'prop-types'; export default function TermOfUse() { - const VITE_CLIENT_PORT = import.meta.env.VITE_CLIENT_PORT; return ( -
    -
    +
    +
    {/* Page Title */}

    Terms of Use @@ -14,7 +13,7 @@ export default function TermOfUse() { {/* Introduction */}
    -

    +

    Welcome to BitBox! By using our platform, you agree to abide by the following terms and conditions. Please read them carefully to understand your rights and responsibilities while using our services.

    @@ -24,7 +23,7 @@ export default function TermOfUse() {

    1. Acceptance of Terms

    -

    +

    By accessing or using BitBox, you acknowledge that you have read, understood, and agree to be bound by these Terms of Use. If you do not agree with any part of these terms, please refrain from using our services.

    @@ -34,7 +33,7 @@ export default function TermOfUse() {

    2. User Responsibilities

    -
      +
      • Provide accurate information when creating an account.
      • Upload projects that respect copyright and are legally permissible.
      • Engage in constructive feedback and collaboration with respect for others.
      • @@ -46,7 +45,7 @@ export default function TermOfUse() {

        3. Project Ownership and Intellectual Property

        -

        +

        Content shared on BitBox remains the property of the user. However, by uploading your projects, you grant BitBox permission to display and distribute your content on the platform.

        @@ -56,7 +55,7 @@ export default function TermOfUse() {

        4. Prohibited Conduct

        -
          +
          • Do not post illegal or harmful content.
          • Do not engage in activities that could harm the platform or other users.
          • Avoid unauthorized access attempts to BitBox systems.
          • @@ -68,7 +67,7 @@ export default function TermOfUse() {

            5. Limitation of Liability

            -

            +

            BitBox shall not be liable for any damages arising from the use of our platform, including lost profits, data, or goodwill.

            @@ -78,7 +77,7 @@ export default function TermOfUse() {

            6. Termination of Access

            -

            +

            We reserve the right to terminate your access to BitBox if you violate these Terms of Use or engage in harmful activities.

            @@ -88,7 +87,7 @@ export default function TermOfUse() {

            7. Changes to Terms

            -

            +

            BitBox reserves the right to update these Terms of Use at any time. Continued use of the platform after changes indicates acceptance of the new terms.

            @@ -98,7 +97,7 @@ export default function TermOfUse() {

            8. Governing Law

            -

            +

            These Terms shall be governed by the applicable laws in your jurisdiction.

            diff --git a/client/src/css/Main.css b/client/src/css/Main.css index fe7e682..212103a 100644 --- a/client/src/css/Main.css +++ b/client/src/css/Main.css @@ -132,12 +132,6 @@ ul { cursor: auto; } -/* Privacy Policy */ -.privacy-policy-container { - margin-top: 40px; - margin-bottom: 40px; -} - .paragraph { margin-bottom: 50px; } @@ -154,11 +148,6 @@ ul { margin-left: 30px; } -.privacy-policy-container { - padding-left: 15%; - padding-right: 15%; -} - /* Term of Use */ .container-T { border-radius: 4px; From e93161147628f92d4ec225e395cecb1527ee240d Mon Sep 17 00:00:00 2001 From: Anuj3553 Date: Fri, 8 Nov 2024 11:00:37 +0530 Subject: [PATCH 29/34] Fix HTML entity references in Privacy Policy component --- client/src/component/Footers/Privacypolicy.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/component/Footers/Privacypolicy.jsx b/client/src/component/Footers/Privacypolicy.jsx index 50237bb..5942a3f 100644 --- a/client/src/component/Footers/Privacypolicy.jsx +++ b/client/src/component/Footers/Privacypolicy.jsx @@ -60,8 +60,8 @@ export default function PrivacyPolicy(props) { our Service or parts of our Service.
          • - Company: Refers to BitBox (also referred to as "the - Company", "We", "Us", or "Our"). + Company: Refers to BitBox (also referred to as "the + Company", "We", "Us", or "Our").
          • Cookies: Small files placed on your device (computer, From da8529bb718d8c58893ffa3676f0ff7ed5af97e1 Mon Sep 17 00:00:00 2001 From: Sawan Date: Fri, 8 Nov 2024 13:59:56 +0530 Subject: [PATCH 30/34] enhances the styling of full blog page --- client/src/component/Blog.jsx | 113 +++++++++++++++++++------- client/src/component/Contributors.jsx | 3 + 2 files changed, 86 insertions(+), 30 deletions(-) diff --git a/client/src/component/Blog.jsx b/client/src/component/Blog.jsx index 2806771..ca082f1 100644 --- a/client/src/component/Blog.jsx +++ b/client/src/component/Blog.jsx @@ -2,6 +2,8 @@ import { useEffect, useState, useRef } from "react"; import PropTypes from 'prop-types'; import { Search } from "lucide-react"; import { Link } from "react-router-dom"; +import { motion } from "framer-motion"; + import img1 from "../assets/blogs/1.webp"; import img2 from "../assets/blogs/2.jpeg"; @@ -112,49 +114,100 @@ export default function BlogPage(props) { }, []); return ( -
            +
            {/* Hero Section */} -
            -
            -

            Explore Our Blog

            -

            Discover stories, insights, and knowledge

            +
            +
            +
            + + Dive into the BitBox Blog! + + + Where Projects Thrive and Connections Come Alive +
            -
            +
            {/* Search and Filter Section */}
            -
            -
            - setSearchTerm(e.target.value)} - /> - +
            +
            +
            + setSearchTerm(e.target.value)} + /> + +
            + +
            + + Create Blog + +
            +
            -
            +
            {categories.map((category) => ( - +
            +

            + {category} +

            +
            + ))}
            -
            - - Create blog - -
            +
            {/* Blog Grid */} @@ -209,7 +262,7 @@ export default function BlogPage(props) {
            -
            +
            {blogPost.content.replace(/<[^>]+>/g, '')}
            diff --git a/client/src/component/Contributors.jsx b/client/src/component/Contributors.jsx index 84ffb66..c212f3b 100644 --- a/client/src/component/Contributors.jsx +++ b/client/src/component/Contributors.jsx @@ -222,6 +222,9 @@ StatCard.propTypes = { icon: PropTypes.node.isRequired, onClick: PropTypes.func, }; +Contributor.propTypes = { + mode: PropTypes.string.isRequired, +}; export default function Contributor(props) { const [contributors, setContributors] = useState([]); From 17756ffd7314ec573286882fb6c8d7b98d191d06 Mon Sep 17 00:00:00 2001 From: Sawan Date: Sat, 9 Nov 2024 21:58:40 +0530 Subject: [PATCH 31/34] Remove cached FAQ.jsx --- client/src/component/FAQ.jsx | 51 ------------------------------------ 1 file changed, 51 deletions(-) delete mode 100644 client/src/component/FAQ.jsx diff --git a/client/src/component/FAQ.jsx b/client/src/component/FAQ.jsx deleted file mode 100644 index ae2e048..0000000 --- a/client/src/component/FAQ.jsx +++ /dev/null @@ -1,51 +0,0 @@ -// component/FAQ.jsx -import React, { useState } from 'react'; -import './FAQ.css'; // Import the CSS file for styling - -const FAQ = () => { - const [activeIndex, setActiveIndex] = useState(null); - - const toggleAnswer = (index) => { - setActiveIndex(activeIndex === index ? null : index); - }; - - return ( -
            -

            Frequently Asked Questions

            - {faqData.map((item, index) => ( -
            -

            toggleAnswer(index)} className="faq-question"> - {item.question} -

            - {activeIndex === index &&

            {item.answer}

            } -
            - ))} -
            - ); -}; - -const faqData = [ - { - question: "What is BitBox?", - answer: "BitBox is a user-friendly platform that simplifies version control and collaboration for developers.", - }, - { - question: "How does BitBox enhance collaboration?", - answer: "BitBox offers intuitive tools that enable both solo programmers and large teams to manage projects efficiently.", - }, - { - question: "How do I get started with BitBox?", - answer: "You can sign up for an account on BitBox and start managing your projects right away.", - }, - { - question: "Is BitBox compatible with modern development workflows?", - answer: "Yes, BitBox seamlessly integrates with modern development workflows, providing fast and reliable performance.", - }, - { - question: "How can I contact support if I need help?", - answer: "You can reach out to support through the 'Contact Us' page or by emailing support@example.com.", - }, -]; - - -export default FAQ; From c4d21f83c5a5746ee6f55cc351c06972378a8054 Mon Sep 17 00:00:00 2001 From: Sawan Date: Sat, 9 Nov 2024 22:23:51 +0530 Subject: [PATCH 32/34] Added discussion forum --- client/package-lock.json | 1 - client/src/App.jsx | 2 + client/src/component/DiscussionForum.jsx | 156 +++++++++++++++++++++++ client/src/component/faq.jsx | 55 ++++++++ package-lock.json | 2 +- 5 files changed, 214 insertions(+), 2 deletions(-) create mode 100644 client/src/component/DiscussionForum.jsx create mode 100644 client/src/component/faq.jsx diff --git a/client/package-lock.json b/client/package-lock.json index 0246cf8..65e9880 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -2045,7 +2045,6 @@ }, "node_modules/@types/react-dom": { "version": "18.3.1", - "dev": true, "license": "MIT", "dependencies": { "@types/react": "*" diff --git a/client/src/App.jsx b/client/src/App.jsx index 5a69abf..2a0844e 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -38,6 +38,7 @@ import "aos/dist/aos.css"; import Collab from "./component/Collab"; import CreateBlog from "./component/CreateBlog"; import UploadProject from "./component/UploadProject"; +import DiscussionForum from "./component/DiscussionForum"; const Layout = ({ children, mode, setProgress, toggleMode, showAlert }) => { return ( @@ -146,6 +147,7 @@ function App() { } /> } /> } /> + } /> } /> diff --git a/client/src/component/DiscussionForum.jsx b/client/src/component/DiscussionForum.jsx new file mode 100644 index 0000000..3da0732 --- /dev/null +++ b/client/src/component/DiscussionForum.jsx @@ -0,0 +1,156 @@ +import { useState, useEffect } from 'react'; + +const DiscussionForum = (props) => { + const [questions, setQuestions] = useState([]); + + // Fetch questions from localStorage + useEffect(() => { + const storedQuestions = localStorage.getItem('questions'); + if (storedQuestions) { + setQuestions(JSON.parse(storedQuestions)); + } + }, []); + + // Save questions to localStorage + const saveQuestions = (updatedQuestions) => { + setQuestions(updatedQuestions); + localStorage.setItem('questions', JSON.stringify(updatedQuestions)); + }; + + // Helper function to save a new question + const addQuestion = (content) => { + const newQuestion = { + id: Date.now().toString(), + content, + answered: false, + answer: '', + }; + + const updatedQuestions = [...questions, newQuestion]; + saveQuestions(updatedQuestions); + }; + + // Helper function to add an answer to a question + const addAnswer = (questionId, answerContent) => { + const updatedQuestions = questions.map((question) => + question.id === questionId + ? { ...question, answered: true, answer: answerContent } + : question + ); + saveQuestions(updatedQuestions); + }; + + // Function to render the Question Card + const renderQuestionCard = (question) => { + return ( +
            +

            {question.content}

            + {question.answered ? ( +
            +

            Answer:

            +

            {question.answer}

            +
            + ) : ( + + )} +
            + ); + }; + + // Function to render the Answer Form + const AnswerForm = ({ questionId }) => { + const [answer, setAnswer] = useState(''); + + const handleSubmit = (e) => { + e.preventDefault(); + if (answer.trim()) { + addAnswer(questionId, answer); + setAnswer(''); + } + }; + + return ( + +
            @@ -141,44 +138,42 @@ function AddProject({ mode }) { GitHub Link setGitHubLink(e.target.value)} className={`w-full mt-1 p-2 border rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none ${mode === 'dark' ? 'bg-gray-700 text-white border-gray-600' : 'bg-white text-gray-900 border-gray-300'}`} placeholder="Enter your project GitHub link" required />
            - {/* Youtube Link */} + {/* YouTube Link */}
            setYouTubeLink(e.target.value)} className={`w-full mt-1 p-2 border rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none ${mode === 'dark' ? 'bg-gray-700 text-white border-gray-600' : 'bg-white text-gray-900 border-gray-300'}`} placeholder="Enter your project YouTube link" required /> -
            +
            {/* Submit Button */}
            @@ -186,9 +181,8 @@ function AddProject({ mode }) {
            )}
            -
            - ) + ); } AddProject.propTypes = { @@ -196,4 +190,4 @@ AddProject.propTypes = { mode: PropTypes.string, }; -export default AddProject; \ No newline at end of file +export default AddProject;