Skip to content

Commit

Permalink
Users can write articles
Browse files Browse the repository at this point in the history
  • Loading branch information
sumanurawat committed Apr 8, 2024
1 parent cfa3213 commit 2eff259
Show file tree
Hide file tree
Showing 11 changed files with 346 additions and 52 deletions.
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"firestore": "^1.1.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-firebase-hooks": "^5.1.1",
"react-router-dom": "^6.22.3",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
Expand Down
6 changes: 5 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import Login from 'components/Login';
import Signup from 'components/Signup';
import Profile from 'components/Profile';
import HomePage from 'components/HomePage';
import Header from 'components/Header';
import Header from 'components/Header/Header';
import UpdateProfile from 'components/UpdateProfile/UpdateProfile';
import Write from 'components/Write/Write';
import EditArticle from 'components/EditArticle/EditArticle';
function App() {

return (
Expand All @@ -21,6 +23,8 @@ function App() {
<Route path="/profile" element={<Profile />} />
<Route path="/home" element={<HomePage />} />
<Route path="/update-profile" element={<UpdateProfile />} />
<Route path="/write" element={<Write />} />
<Route path="/EditArticle/:articleId" element={<EditArticle />} />
</Routes>
</div>

Expand Down
70 changes: 70 additions & 0 deletions src/components/EditArticle/EditArticle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// src/components/EditArticle.js
import React, { useState, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { db } from 'firebase-config';
import { doc, getDoc, updateDoc, serverTimestamp } from 'firebase/firestore';

function EditArticle() {
const [title, setTitle] = useState('');
const [body, setBody] = useState('');
const { articleId } = useParams(); // Capture the articleId from the URL
const navigate = useNavigate();

useEffect(() => {
const fetchArticle = async () => {
const articleRef = doc(db, 'articles', articleId);
const docSnap = await getDoc(articleRef);
if (docSnap.exists()) {
setTitle(docSnap.data().title);
setBody(docSnap.data().body);
} else {
console.log("No such document!");
navigate('/profile'); // Redirect if the article doesn't exist
}
};
fetchArticle();
}, [articleId, navigate]);

const handleSubmit = async (e) => {
e.preventDefault();
const articleRef = doc(db, 'articles', articleId);
await updateDoc(articleRef, {
title,
body,
updatedAt: serverTimestamp(),
});
navigate('/profile'); // Navigate to the profile page after successful update
};

return (
<div>
<h2>Edit Your Article</h2>
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="title">Title:</label>
<input
id="title"
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
required
/>
</div>
<div>
<label htmlFor="body">Story:</label>
<textarea
id="body"
value={body}
onChange={(e) => setBody(e.target.value)}
required
rows="10"
style={{ width: '100%' }}
/>
</div>
<button type="submit">Update Article</button>
</form>
</div>
);
}

export default EditArticle;
23 changes: 0 additions & 23 deletions src/components/Header.js

This file was deleted.

25 changes: 25 additions & 0 deletions src/components/Header/Header.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.header {
background-color: #007bff; /* A nice shade of blue */
padding: 10px 20px; /* Add some padding around the header */
}

.nav-links {
list-style: none; /* Remove default list styling */
padding: 0;
margin: 0;
display: flex; /* Display links in a row */
gap: 10px; /* Add some space between links */
}

.nav-link {
text-decoration: none; /* Remove underline from links */
color: white; /* Make text color white for contrast */
background-color: #0056b3; /* A slightly darker blue for buttons */
padding: 10px 15px; /* Add padding around the text */
border-radius: 5px; /* Round the corners */
transition: background-color 0.3s; /* Smooth background color transition on hover */
}

.nav-link:hover {
background-color: #003785; /* Darken button on hover */
}
25 changes: 25 additions & 0 deletions src/components/Header/Header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { useAuth } from 'hooks/useAuth';
import './Header.css'; // Import the CSS file

function Header() {
const { currentUser } = useAuth(); // This hook checks if a user is logged in

return (
<header className="header">
<nav>
{currentUser && (
<ul className="nav-links">
{/* Use the Link component as a button */}
<li><Link to="/home" className="nav-link">Home</Link></li>
<li><Link to="/profile" className="nav-link">Profile</Link></li>
<li><Link to="/write" className="nav-link">Write</Link></li>
</ul>
)}
</nav>
</header>
);
}

export default Header;
74 changes: 46 additions & 28 deletions src/components/Profile.js
Original file line number Diff line number Diff line change
@@ -1,58 +1,76 @@
// src/components/Profile.js
import React, { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { auth, db } from 'firebase-config';
import { signOut } from 'firebase/auth';
import { doc, getDoc } from 'firebase/firestore';
import { auth, db } from 'firebase-config'; // Adjust the import path as necessary
import { signOut, onAuthStateChanged } from 'firebase/auth';
import { doc, getDoc, collection, query, where, getDocs, deleteDoc } from 'firebase/firestore';
import UserArticlesList from 'components/UserArticlesList/UserArticlesList'; // Import the new component


function Profile() {
const navigate = useNavigate();
const user = auth.currentUser;
const [profileData, setProfileData] = useState(null);
const [userArticles, setUserArticles] = useState([]);

useEffect(() => {
const fetchUserProfile = async () => {
const unsubscribe = onAuthStateChanged(auth, (user) => {
if (user) {
const userRef = doc(db, "users", user.uid);
const userProfile = await getDoc(userRef);
if (userProfile.exists()) {
setProfileData(userProfile.data());
} else {
// User does not have a profile yet, could navigate to create profile
navigate('/update-profile');
}
fetchUserProfile(user.uid);
} else {
// If no user is logged in, navigate to login or another appropriate page
navigate('/login');
}
};
});

fetchUserProfile();
}, [navigate, user]);
// Clean up the subscription
return () => unsubscribe();
}, [navigate]);

const fetchUserProfile = async (userId) => {
// Fetch user profile
const userRef = doc(db, "users", userId);
const userProfile = await getDoc(userRef);
if (userProfile.exists()) {
setProfileData(userProfile.data());
} else {
navigate('/update-profile');
}

// Fetch user's articles
const articlesRef = collection(db, "articles");
const q = query(articlesRef, where("userId", "==", userId));
const querySnapshot = await getDocs(q);
const articles = querySnapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
setUserArticles(articles);
};

const handleLogout = async () => {
try {
await signOut(auth);
navigate('/'); // Navigate to the root or login page after logout
} catch (error) {
await signOut(auth).catch((error) => {
console.error('Logout failed', error);
}
});
navigate('/');
};

const handleEditProfile = () => {
// Navigate to the update profile page
navigate('/update-profile');
const handleDelete = async (articleId) => {
const articleRef = doc(db, "articles", articleId);
await deleteDoc(articleRef);
// Update the UI by removing the deleted article
setUserArticles(userArticles.filter(article => article.id !== articleId));
};

return (
<div>
<h1>Welcome to your profile</h1>
{user && <p>Email: {user.email}</p>}
{profileData && (
<>
<p>Email: {auth.currentUser?.email}</p>
<p>Name: {profileData.name}</p>
<p>Date of Birth: {profileData.dateOfBirth}</p>
<p>Location: {profileData.location}</p>
<button onClick={() => navigate('/update-profile')}>Edit Profile</button>
<button onClick={handleLogout}>Logout</button>
</>
)}
<button onClick={handleEditProfile}>Edit Profile</button>
<button onClick={handleLogout}>Logout</button>
<UserArticlesList articles={userArticles} onDelete={handleDelete} />
</div>
);
}
Expand Down
69 changes: 69 additions & 0 deletions src/components/UserArticlesList/UserArticlesList.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
.articles-container {
margin: 20px auto;
padding: 20px;
background-color: #f0f0f0; /* Light gray background */
border-radius: 8px; /* Rounded corners for the container */
max-width: 800px; /* Set a max-width for better reading experience on large screens */
}

/* Style the list to remove bullets and padding */
ul {
list-style-type: none; /* Remove bullets */
padding: 0; /* Remove default padding */
margin: 0; /* Remove default margin */
}

.article-item {
display: flex;
flex-direction: column; /* Stack content vertically */
margin-bottom: 20px;
padding: 20px;
background-color: white;
border-radius: 5px;
border: 1px solid #ddd; /* Add a border for distinction */
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.15); /* Stronger shadow for more depth */
transition: box-shadow 0.3s ease; /* Smooth transition for shadow on hover */
}

.article-item:hover {
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.25); /* Enhanced shadow when hovered */
}

.article-title {
font-weight: bold;
color: #333; /* Darker text for the title */
margin-bottom: 10px;
}

.article-body {
color: #666; /* Lighter text for the body */
margin-bottom: 15px; /* Add space before buttons */
}

.button {
padding: 10px 15px;
margin-right: 10px;
border: none;
border-radius: 5px;
cursor: pointer; /* Cursor pointer to indicate it's clickable */
transition: all 0.2s; /* Smooth transition for all properties */
align-self: flex-start; /* Align buttons to the start of the flex container */
}

.edit-button {
background-color: #4CAF50; /* Green background for edit */
color: white;
}

.edit-button:hover {
background-color: #45a049; /* Slightly darker green on hover */
}

.delete-button {
background-color: #f44336; /* Red background for delete */
color: white;
}

.delete-button:hover {
background-color: #da190b; /* Slightly darker red on hover */
}
Loading

0 comments on commit 2eff259

Please sign in to comment.