Hi ! Today we will see How to make Trello system clone whit R-F-R
In this tutorial there will be:
- Create a project then entered it whit Redux
- Create a card in the project then put lists
File structure
src └──app └── components ├── Home.js ├── InProject.js ├── ShowCards.js └──store ├── store.js ├── ProjectSlice.js ├── app(router).js
Packages
Install the packages below :
🤘 Redux "@reduxjs/toolkit": "^1.6.2" "react-redux": "^7.2.6" 🔥 Firebase "firebase": "^9.5.0" "react-firebase-hooks": "^4.0.1" ⬅⬇➡ Router "react-router": "^5.2.1" "react-router-dom": "^5.3.0"
Router
Create the following files in your src folder:
Home.js
InProject
Then put them in the router.
app(router).js
import React from "react"; import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; import home from './Home' import project from './InProject' <Router> <Switch> <Route exact path="/" component={home} /> <Route exact path="/project" component={project} /> </Switch> </div> </Router>
Create a project
Go to the Home.js file
We are going to create a new function which will be called {createProject}. With Firestore, we will create a new document in the 'project' collection.
In it, we will put two different fields, one for the creation date timestamp
, and the other titleProject which will be the value of the input (defined by a Ref)
Home.js
const inputTitleProject = useRef(""); const db = firebase.firestore(); const createProject = useCallback(async event => { event.preventDefault(); if (inputTitle.current.value !== "") { db.collection("project").add({ timestamp: firebase.firestore.FieldValue.serverTimestamp(), titleProject: inputTitle.current.value, }); } }) return ( /* the onSubmit will execute the "createProject" function. */ <form onSubmit={createProject}> <input ref={inputTitleProject} placeholder="Your title project" > <button type="submit"> Create the project ! </button> </form> )
When you go to Firestore console.firebase.google.com
it would look like this:
Display all project
With the useCollection function, we can choose any collection. For this case, we're going to use the 'project' collection. Then, we will make a docs.map, where we will put all the fields.
To be able to read the project, we will create a file named ShowProject.js
, we will display the project inside.
Home.js
import { useCollection } from "react-firebase-hooks/firestore" import ShowProject from './ShowProject.js' const db = firebase.firestore(); const [listproject] = useCollection( db .collection("project") ); return( /* Don't forget to keep the key and the id, it will be important for the future. */ {projectlist?.docs.map((doc) => ( <ShowProject key={doc.id} id={doc.id} titleProject={doc.data().titleProject} /> ))} )
We will import everything we put in the MessageShow, then we just have to use {title} so that the text of the field is displayed.
ShowProjects.js
function ShowProject({id, titleProject}) { return ( <div> <p>{titleProject}</p> </div> )
🐱🚀 Redux joinded the chat
Create a new Store folder. In it, you will create a file named Store.js
. We will inserted a small-code
store.js
/* We import the configureStore from redux */ import { configureStore } from "@reduxjs/toolkit"; import projectSlice from "./ProjectSlice"; export const store = configureStore({ reducer: { project: projectSlice, }, });
Then you create a new file ProjectSlice.js
ProjectSlice.js
import { createSlice } from "@reduxjs/toolkit"; /* We define the initial state */ const initialState = { projectId: null, }; export const projectSlice = createSlice({ name: "project", initialState, reducers: { setProject: (state, action) => { state.projectId = action.payload.projectId; state.projectName = action.payload.projectName; }, }, }); export const { setProjectInfo } = projectSlice.actions; export const selectProjectId = (state) => state.project.projectId; export const selectProjectName = (state) => state.project.projectName; export default projectSlice.reducer;
We modify our index.js
index.js
/* We import our redux tools */ import { Provider } from "react-redux" import { store } from "./store/Store" /* We add a provider */ ReactDOM.render( <React.StrictMode> <Provider store={store}> <App /> </Provider> </React.StrictMode>, document.getElementById('root') );
Now, we come back to our ShowProject.js
file
ShowProject.js
function ShowProject({id, title, name, photoURL}) { const setProject = () => { dispatch( setProjectInfo({ projectId: id, }) ); history.push(`/project/{$id}`); }; return ( /* We modify our div, and when we click on it, it executes the 'setProject' function We also define the cursor as a pointer */ <div onClick={setProject} style={{cursor: 'pointer'}}> <p> {title} </p> </div> )
We now come back to our app (router).js
app(router).js
/* You just add these two little lines. We can put the id in the router. When it is on the url /project/{id}/, it will display the component 'InProject.js' */ import InProject from './InProject.js' return ( <Route exact path="/project/:id" component={InProject} /> )
In Project
Create Card
Go to the InProject.js
file
The system will be almost the same as for the Home.js
We are going to create a new function which will be called {createCard}. With Firestore, we will create a new document in the collection project/{projectId}/card/
In it, we will put two different fields, one for the creation date timestamp
, and the other titleCard which will be the value of the input (defined by a Ref)
InProject.js
import { useCollection } from "react-firebase-hooks/firestore" import { selectProjectId } from './store/ProjectSlice.js' import { useSelector } from "react-redux"; const inputTitleCard = useRef(""); const db = firebase.firestore(); const projectId = useSelector(postId); const createCard = useCallback(async event => { event.preventDefault(); if (inputTitle.current.value !== "") { db.collection("project").doc(projectId).collecton("card").add({ timestamp: firebase.firestore.FieldValue.serverTimestamp(), titleProject: inputTitle.current.value, }); } }) return ( /* the onSubmit will execute the "createCard" function. */ <form onSubmit={createCard}> <input ref={inputTitleCard} placeholder="Title of your card" > <button type="submit"> Create the Card ! </button> </form> )
Read Card
It is almost identical to Home.js
With the useCollection function, we can choose any collection. For this case, we're going to use the project/{projectId}/card
collection. Then, we will make a docs.map, where we will put all the fields.
InProject.js
import { useCollection } from "react-firebase-hooks/firestore" const db = firebase.firestore(); const [listcard] = useCollection( db .collection("project") .doc(projectId) .collection("card") ); return( {frontmessagez?.docs.map((doc) => { const { titleCard} = doc.data() return ( <> <div> <p> {titleCard} </p> </div> </> ); })}
CreateList & ReadList
The system is the same as for the Home.js
& InProject.js
🥖 Et voilà !
You've finished your Trello system clone whit React, Firebase, Redux.
, now all you have to do is put css ✨?
Donations-Support
Bitcoin | Ethereum |
---|---|
3FahtNWC4tmZh1B72vz44TvBN2jHaQSnh4 | 0x7cad12dfd11bce3f29b96260b4739caa32c89a86 |
Top comments (0)