Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Efficiently add github and youtube link #434

Merged
merged 3 commits into from
Nov 10, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 69 additions & 75 deletions client/src/component/AddProject.jsx
Original file line number Diff line number Diff line change
@@ -1,63 +1,70 @@
import PropTypes from 'prop-types';
import { useContext, useState, useRef, useEffect } from 'react';
import { useContext, useState, useRef } from 'react';
import projectContext from '../context/projectContext';
import { toast } from 'react-toastify';

// Assets
// import projectDummyImage from '../assets/images/Others/projects.png'
function AddProject({ mode }) {
const [isModalOpen, setIsModalOpen] = useState(false);
const [isLoading, setIsLoading] = useState(false);

const context = useContext(projectContext);
// Destructure the addProject from context
const { addProject } = context;

// image, date, title, description, gitHubLink, youTubeLink, tags
const [project, setProject] = useState({ image: "", date: "", title: "", description: "", gitHubLink: "", youTubeLink: "", tags: "" });
const refClose = useRef(null);

const handleSubmit = () => {
if (project.title.trim() === "") {
toast.error("Title is required");
return;
}
// Modify YouTube link
const modifiedYouTubeLink = modifyYouTubeLink(project.youTubeLink);
// Add project API call
addProject(project.title, project.description, project.gitHubLink, modifiedYouTubeLink, project.tags); // Pass modifiedYouTubeLink instead of project.youTubeLink
refClose.current.click();
setProject({ title: "", description: "", gitHubLink: "", youTubeLink: "" });
toast.success("Project Added Successfully");
};
// Separate state for each input
const [title, setTitle] = useState("");
const [description, setDescription] = useState("");
const [gitHubLink, setGitHubLink] = useState("");
const [youTubeLink, setYouTubeLink] = useState("");
const [tags, setTags] = useState("");

const handleKeyDown = (e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Prevent form submission on Enter key press
handleSubmit(); // Manually handle the click event
}
}
const refClose = useRef(null);

useEffect(() => {
const handleKeyPress = (event) => {
if (event.key === "Enter" && project.title.trim() !== "") {
handleSubmit();
// Handle form submission
const handleSubmit = async (e) => {
e.preventDefault(); // Prevent default form submission
setIsLoading(true);
try {
if (title.trim() === "") {
toast.error("Title is required");
return;
}
};

document.addEventListener("keypress", handleKeyPress);
// Validate GitHub Link
if (gitHubLink && !/^https:\/\/github\.com\//.test(gitHubLink)) {
toast.error("Please enter a valid GitHub URL.");
return;
}

return () => {
document.removeEventListener("keypress", handleKeyPress);
};
// eslint-disable-next-line
}, [project.title]); // Only re-run the effect if project.title changes
// Validate YouTube Link
if (youTubeLink && !/^https:\/\/(www\.)?youtube\.com\/watch\?v=/.test(youTubeLink)) {
toast.error("Please enter a valid YouTube URL.");
return;
}

const onChange = (e) => {
// Able to write in the input field
setProject({ ...project, [e.target.name]: e.target.value });
// Modify YouTube link to embed format
const modifiedYouTubeLink = modifyYouTubeLink(youTubeLink);

// Call addProject function from context
await addProject(title, description, gitHubLink, modifiedYouTubeLink, tags);
toast.success("Project Added Successfully");
// console.log(title + " " + description + " " + gitHubLink + " " + youTubeLink)
// Clear form
setTitle("");
setDescription("");
setGitHubLink("");
setYouTubeLink("");
setTags("");

// Close modal
refClose.current.click();
} catch (error) {
toast.error("Failed to upload the project. Please try again.");
} finally {
setIsLoading(false); // End loading state
}
};

// Function to modify YouTube link
// Function to modify YouTube link (from watch to embed URL)
const modifyYouTubeLink = (link) => {
if (link.includes("youtube.com/watch?v=")) {
const videoId = link.split("youtube.com/watch?v=")[1];
Expand All @@ -67,7 +74,6 @@ function AddProject({ mode }) {
}
};

// Upload Project Modal
const themeStyles = mode === 'dark' ? 'bg-gray-800 text-white' : 'bg-white text-gray-900';

return (
Expand All @@ -82,16 +88,9 @@ function AddProject({ mode }) {
{isModalOpen && (
<div className="fixed flex z-[99999999999] justify-center items-center inset-0 bg-black bg-opacity-50">
{/* Modal Content */}
<div
className={`relative top-22 md:top-12 w-full max-w-md p-6 mx-2 my-8 bg-white rounded-lg shadow-lg overflow-auto ${themeStyles}`}
style={{ maxHeight: '800px', fontSize: '14px' }}
>
<div className={`relative top-22 md:top-12 w-full max-w-md p-6 mx-2 my-8 bg-white rounded-lg shadow-lg overflow-auto ${themeStyles}`} style={{ maxHeight: '800px', fontSize: '14px' }}>
{/* Close Button in Top Right */}
<button
onClick={() => setIsModalOpen(false)}
className="absolute top-0 right-10 text-gray-500 hover:text-gray-700"
style={{ fontSize: '42px' }}
>
<button onClick={() => setIsModalOpen(false)} className="absolute top-0 right-10 text-gray-500 hover:text-gray-700" style={{ fontSize: '42px' }}>
&times;
</button>

Expand All @@ -109,9 +108,8 @@ function AddProject({ mode }) {
type="text"
id="title"
name="title"
value={project.title}
onChange={onChange}
onKeyDown={handleKeyDown}
value={title}
onChange={(e) => setTitle(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 title"
required
Expand All @@ -126,11 +124,10 @@ function AddProject({ mode }) {
<textarea
id="description"
name="description"
value={project.description}
onChange={onChange}
onKeyDown={handleKeyDown}
value={description}
onChange={(e) => setDescription(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 Project Title Here *"
placeholder="Enter Project Description"
required
></textarea>
</div>
Expand All @@ -141,59 +138,56 @@ function AddProject({ mode }) {
GitHub Link
</label>
<input
type="url"
type="text"
id="githubLink"
name="githubLink"
value={project.gitHubLink}
onChange={onChange}
onKeyDown={handleKeyDown}
value={gitHubLink}
onChange={(e) => 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
/>
</div>

{/* Youtube Link */}
{/* YouTube Link */}
<div>
<label htmlFor="youtubeLink" className={`block text-lg font-semibold ${mode === 'dark' ? 'text-gray-300' : 'text-gray-700'}`}>
Youtube Link
YouTube Link
</label>
<input
type="url"
type="text"
id="youtubeLink"
name="youtubeLink"
value={project.youTubeLink}
onChange={onChange}
onKeyDown={handleKeyDown}
value={youTubeLink}
onChange={(e) => 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
/>
</div>
</div>

{/* Submit Button */}
<div className="text-center mt-4">
<button
disabled={project.title.trim() === ""}
disabled={isLoading || title.trim() === ""}
type="submit"
className={`w-full py-2 rounded-md text-lg font-semibold ${mode === 'dark' ? 'bg-blue-700 hover:bg-blue-600' : 'bg-blue-600 hover:bg-blue-700'} text-white focus:outline-none focus:ring-2 focus:ring-blue-400`}
>
Upload Project
{isLoading ? "Uploading..." : "Upload Project"}
</button>
</div>
</form>
</div>
</div>
)}
</div>

</div>
)
);
}

AddProject.propTypes = {
showAlert: PropTypes.func,
mode: PropTypes.string,
};

export default AddProject;
export default AddProject;
Loading