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)