diff --git a/client/src/App.jsx b/client/src/App.jsx index f57a36f..2000cb6 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -39,6 +39,8 @@ import "aos/dist/aos.css"; import Collab from "./component/Collab"; import FAQ from "./component/Faq"; import CreateBlog from "./component/CreateBlog"; +import Projects from "./component/Projects"; +import UploadProject from "./component/UploadProject"; // Main Layout Component const Layout = ({ children, mode, setProgress, toggleMode, showAlert }) => { @@ -53,6 +55,7 @@ const Layout = ({ children, mode, setProgress, toggleMode, showAlert }) => { blog="Blogs" discussion="Discussion" contributors="Contributors" + projects="Projects" Feedback="Feedback" showAlert={showAlert} mode={mode} @@ -147,6 +150,8 @@ function App() { } /> } /> } /> + } /> + } /> } /> } /> } /> diff --git a/client/src/component/Navbar.jsx b/client/src/component/Navbar.jsx index 5c367f3..7293845 100644 --- a/client/src/component/Navbar.jsx +++ b/client/src/component/Navbar.jsx @@ -225,6 +225,16 @@ function Navbar(props) { {props.contributors} +
  • + + {props.projects} + +
  • @@ -590,6 +600,7 @@ Navbar.propTypes = { blog: PropTypes.string, about: PropTypes.string, contributors: PropTypes.string, + projects: PropTypes.string, profile: PropTypes.string, mode: PropTypes.string, toggleMode: PropTypes.func, diff --git a/client/src/component/Projects.jsx b/client/src/component/Projects.jsx new file mode 100644 index 0000000..67a7d6b --- /dev/null +++ b/client/src/component/Projects.jsx @@ -0,0 +1,103 @@ +import React, { useState, useEffect } from 'react'; +import PropTypes from "prop-types"; +import { useNavigate } from 'react-router-dom'; +import axios from 'axios'; + +const Projects = ({ mode }) => { + const navigate = useNavigate(); + const [projects, setProjects] = useState([]); // State to store fetched projects + const [loading, setLoading] = useState(true); // State for loading state + const [error, setError] = useState(null); // State for error handling + + useEffect(() => { + // Fetch the data from the API when the component mounts + const fetchProjects = async () => { + try { + const response = await axios.get('http://localhost:5000/api/showcaseProjects/all-projects'); + setProjects(response.data); // Store the fetched projects in state + setLoading(false); // Set loading to false after data is fetched + } catch (err) { + setError('Error fetching projects'); + setLoading(false); // Set loading to false if an error occurs + } + }; + + fetchProjects(); // Call the function to fetch data + }, []); // Empty dependency array means this effect runs once on mount + + const handleButtonClick = () => { + navigate('/uploadProject'); + }; + + if (loading) { + return
    Loading...
    ; + } + + if (error) { + return
    {error}
    ; + } + + return ( +
    +
    +

    + Projects Showcase +

    + +
    +
    + {projects.map((project, index) => ( +
    +
    +

    + {project.title} +

    +

    + {project.description} +

    +
    + + GitHub + + {project.deploymentLink && ( + + Live Demo + + )} +
    +
    +
    + ))} +
    +
    + ); +}; + +Projects.propTypes = { + mode: PropTypes.string, +}; + +export default Projects; diff --git a/client/src/component/UploadProject.jsx b/client/src/component/UploadProject.jsx index b76c41c..b79b50a 100644 --- a/client/src/component/UploadProject.jsx +++ b/client/src/component/UploadProject.jsx @@ -1,27 +1,163 @@ -import '../css/UploadProject.css' -import PropTypes from 'prop-types'; -import AddProject from './AddProject'; +import React, { useState } from 'react'; +import PropTypes from "prop-types"; +import { useNavigate } from 'react-router-dom'; + + +const UploadProject = ({ mode }) => { + const navigate = useNavigate(); + const [formData, setFormData] = useState({ + title: '', + description: '', + githubLink: '', + deploymentLink: '', + projectFiles: null, + }); + + const handleChange = (e) => { + const { name, value, type, files } = e.target; + if (type === 'file') { + setFormData((prevData) => ({ + ...prevData, + [name]: files[0], + })); + } else { + setFormData((prevData) => ({ + ...prevData, + [name]: value, + })); + } + }; + + const handleSubmit = async (e) => { + e.preventDefault(); + + try { + const response = await fetch('http://localhost:5000/api/showcaseProjects/post-project', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(formData), + }); + + if (!response.ok) { + throw new Error('Failed to submit project'); + } + + const data = await response.json(); + console.log('Project submitted successfully:', data); + navigate('/projects'); + + // Clear the form after submission + setFormData({ + title: '', + description: '', + githubLink: '', + deploymentLink: '', + }); + + // Optionally, you can redirect the user or display a success message + } catch (error) { + console.error('Error submitting project:', error); + } + }; + + const themeStyles = mode === 'dark' ? 'bg-gray-800 text-white' : 'bg-white text-gray-900'; -function UploadProject(props) { return ( -
    -
    +
    +

    + Upload Your Project +

    + +
    + {/* Project Title */} +
    + + +
    + + {/* Project Description */} +
    + + +
    + + {/* 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;