Open In App

Building a Social Media Dashboard with React Hooks and Firebase Firestore

Last Updated : 25 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

The Social Media Dashboard project aims to develop a web application that will enable its users to post content, view submitted posts and hide posts based on categories. The application will be built using React with Hooks for state management and Firebase Firestore for storing and retrieving data.

Output Preview:

Screenshot-18

Preview Image

Prerequisites:

Approach

  • First design a user-friendly interface for seamless navigation and interaction.
  • Utilize React Hooks for managing component state and lifecycle.
  • Integrate Firebase Firestore to store and retrieve post data in real-time.
  • Implement features like write posts, submit post, show all posts, and hide posts.

Steps to create the project

Step 1: Create a reactJS application by using this command

npx create-react-app social-media-dashboard

Step 2: Navigate to project directory

cd social-media-dashboard

Step 3: Install the necessary packages/libraries in your project using the following commands.

npm install firebase

FireBase Configuration : https://www.geeksforgeeks.org/how-to-setup-a-firebase-for-your-react-project/

Project structure:

Screenshot-(19)

Project Structure

The updated dependencies in package.json file will look like:

"dependencies": {
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "firebase": "^10.10.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  }

Example: This example show where users can post content, view submitted posts, and hide posts based on categories.

CSS
/* index.css */
body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
        'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
        sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

code {
    font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
        monospace;
}

/* Dashboard.css */
.dashboard {
    max-width: 800px;
    margin: 0 auto;
    padding: 20px;
}

.post-form {
    margin-bottom: 20px;
}

.post-actions {
    margin-bottom: 20px;
}

.post-list {
    margin-top: 20px;
}

/* PostList.css */
.post-list {
    margin-top: 20px;
}

.post {
    background-color: #997878;
    border: 1px solid #ddd;
    padding: 10px;
    margin-bottom: 10px;
}

.post p {
    margin: 0;
}

.post button {
    margin: 10px;
}

.all-posts {
    margin-top: 20px;
}

.all-posts h2 {
    margin-bottom: 10px;
}

.all-posts .post {
    background-color: #3d3333;
}

.all-posts button {
    margin-top: 10px;
}

.submitBu {
    display: flex;
    justify-content: center;
    color: white;
    background-color: rgb(46, 46, 76);
    border-radius: 5px;
}

.box {
    width: 100%;
    height: 100px;
    resize: vertical;
}

.showCa {
    margin-right: 10px;
    color: white;
    background-color: dimgray;
    border-radius: 10px;
}

.title {
    color: chocolate;
    text-align: center;
    text-decoration: underline;
}
JavaScript
//Dashboard.js

import React, { useState, useEffect } from 'react';
import {
    getPostsFromRealtimeDatabase,
    addPostToRealtimeDatabase,
    deletePostFromRealtimeDatabase
} from './firebase';
import PostList from './PostList';

const Dashboard = () => {
    const [posts, setPosts] = useState([]);
    const [newPostContent, setNewPostContent] = useState('');
    const [showAllPosts, setShowAllPosts] = useState(false);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        fetchPosts();
    }, []);

    const fetchPosts = async () => {
        try {
            const postsData = await getPostsFromRealtimeDatabase();
            setPosts(postsData);
            setLoading(false);
        } catch (error) {
            console.error('Error fetching posts:', error);
            setLoading(false);
        }
    };

    const handlePostSubmit = async (e) => {
        e.preventDefault();
        if (newPostContent.trim() !== '') {
            try {
                await addPostToRealtimeDatabase(newPostContent);
                setNewPostContent('');
                // Fetch posts after adding a new post
                fetchPosts();
            } catch (error) {
                console.error('Error adding post:', error);
            }
        }
    };

    const handleDeletePost = async (postId) => {
        try {
            await deletePostFromRealtimeDatabase(postId);
            // Fetch posts after deleting a post
            fetchPosts();
        } catch (error) {
            console.error('Error deleting post:', error);
        }
    };

    const handleShowAllPosts = () => {
        setShowAllPosts(true);
    };

    const handleHidePosts = () => {
        setShowAllPosts(false);
    };

    return (
        <div className="dashboard">
            <h1 className="title">Social Media Dashboard</h1>
            <div className="post-form">
                <form onSubmit={handlePostSubmit}>
                    <textarea
                        value={newPostContent}
                        onChange={(e) => setNewPostContent(e.target.value)}
                        placeholder="Write your post here..." className="box"
                        required>
                    </textarea>
                    <button type="submit" className="submitBu">
                        Submit Post
                    </button>
                </form>
            </div>
            <div className="post-actions">
                <button onClick={handleShowAllPosts}
                    className="showCa">Show My Category
                </button>
                <button onClick={handleHidePosts}
                    className="showCa">Hide Posts
                </button>
            </div>
            <div className="post-list">
                {loading && <p>Loading...</p>}
                {!loading && showAllPosts && posts.length > 0 &&
                    <PostList posts={posts} onDelete={handleDeletePost} />}
                {!loading && showAllPosts && posts.length === 0 &&
                    <p>There are no posts.</p>}
            </div>
        </div>
    );
};

export default Dashboard;
JavaScript
//PostList.js

import React, { useState } from 'react';

const PostList = ({ posts, onDelete }) => {
    const [showAllPosts, setShowAllPosts] = useState(false);

    const handleClosePosts = () => {
        setShowAllPosts(false);
    };

    return (
        <div className="post-list">
            {posts.length === 0 && showAllPosts && (
                <p>There are no posts.</p>
            )}
            {showAllPosts && (
                <React.Fragment>
                    <div className="all-posts">
                        <button onClick={handleClosePosts}
                            className="showCa">Close
                        </button>
                        <h2>All Posts</h2>
                        {posts.map(post => (
                            <div key={post.id} className="post">
                                <p>{post.content}</p>
                                <button onClick={
                                    () => onDelete(post.id)}
                                    className="showCa">Delete
                                </button>
                            </div>
                        ))}
                    </div>
                </React.Fragment>
            )}
            {!showAllPosts && posts.length > 0 && (
                <button onClick={
                    () => setShowAllPosts(true)}
                    className="showCa">Show All Posts
                </button>
            )}
        </div>
    );
};

export default PostList;
JavaScript
//firebase.js

import { initializeApp } from 'firebase/app';
import {
    getDatabase,
    ref, push,
    get, remove
} from 'firebase/database';

const firebaseConfig = {
    apiKey: "Your_API_Key",
    authDomain: "",
    projectId: "",
    storageBucket: "",
    messagingSenderId: "",
    appId: "",
    databaseURL: "",
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);

// Initialize Realtime Database
const db = getDatabase(app);

export const addPostToRealtimeDatabase = async (content) => {
    try {
        const postsRef = ref(db, 'posts');
        await push(postsRef, {
            content: content,
            // Add timestamp for post creation
            createdAt: new Date().toISOString()
        });
        console.log('Post added successfully');
    } catch (error) {
        console.error('Error adding post:', error);
        // Propagate the error to the caller
        throw error;
    }
};
export const getPostsFromRealtimeDatabase = async () => {
    try {
        const postsRef = ref(db, 'posts');
        const snapshot = await get(postsRef);
        const postsData = [];
        snapshot.forEach((childSnapshot) => {
            postsData.push({
                id: childSnapshot.key,
                ...childSnapshot.val()
            });
        });
        return postsData;
    } catch (error) {
        console.error('Error fetching posts:', error);
        throw error;
    }
};

export const deletePostFromRealtimeDatabase = async (postId) => {
    try {
        const postRef = ref(db, `posts/${postId}`);
        await remove(postRef);
        console.log('Post deleted successfully');
    } catch (error) {
        console.error('Error deleting post:', error);
        throw error;
    }
};
JavaScript
//App.js

import React, { useEffect, useState } from 'react';
import Dashboard from './Dashboard';
import PostList from './PostList';

const App = () => {
    const [posts, setPosts] = useState([]);
    return (
        <div className="App">
            <Dashboard />
            <PostList posts={posts} />
        </div>
    );
};

export default App;

Step to Run Application: Run the application using the following command from the root directory of the project

npm start

Output: Your project will be shown in the URL http://localhost:3000/

social media dashboard with react hooks and firebase

output




Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads