DEV Community

Cover image for Qu'est-ce qu'un projet MERN Stack et comment créer une application CRUD avec? Partie 2/2, Tutoriel
Gérard Cubaka
Gérard Cubaka

Posted on

Qu'est-ce qu'un projet MERN Stack et comment créer une application CRUD avec? Partie 2/2, Tutoriel

Introduction

Dans la première partie de cet article (dont voici), nous avons défini ce qu'est un projet MERN Stack et exploré les raisons pour lesquelles cette ensemble technologique suscite tant d'intérêt dans la communauté du développement web.

Dans cette deuxième partie nous nous concentrerons sur la création d'une application CRUD basique qui permet aux utilisateurs de créer, lire, modifier et supprimer les données dans la base de données en utilisant les technologies MERN.

Ces opérations CRUD seront implémentées côté serveur (avec Node.js et Express.js) pour exposer les endpoints REST API appropriés. Côté client (avec React.js), on pourra alors utiliser ces endpoints pour effectuer les interactions CRUD avec la base de données MongoDB.

C'est partie pour découvrir comment créer une application CRUD avec l'ensemble technologique MERN.

Construire un CRUD de base à l'aide de la pile MERN

Configuration de l'environnement

Avant de commencer, assurez-vous que les éléments suivants sont installés sur votre machine de développement.

Etape1: configurer le projet

  1. Créez un nouveau répertoire de projet et initialisez un nouveau projet Node.js :
   mkdir mern-crud-blog
   cd mern-crud-blog
   npm init -y
Enter fullscreen mode Exit fullscreen mode
  1. Installez les dépendances requises :
   npm install express mongoose body-parser cors
Enter fullscreen mode Exit fullscreen mode
  1. Installez React du côté client :
   npm install -D vite
   cd client 
   npm install react-dom react-scripts axios
Enter fullscreen mode Exit fullscreen mode
  1. Mettre en plae la sutrure du projet:
mern-crud-blog
  ├── client
  │   └── public
  │   |   └── index.html
  |   |   └── images and more.....
  │   └── src
  │       ├── components
  │       ├── App.jsx
  │       └── index.jsx
  │       └── package.json
  ├── server.js
  └── package.json
Enter fullscreen mode Exit fullscreen mode

Etape2: Implémenter le backend (Node.js avec Express et MongoDB)

  1. Créez un fichier nommé server.js dans le répertoire racine et ajouter le code suivant :

// server.js 

//1.Création du serveur.......................................

const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');

const app = express();
const port = 5000;

// Activation de CORS pour autoriser les requêtes en provenance d'autres serveurs
app.use(cors());

// Code nécessaire pour analyser le body HTML dans la réponse
app.use(bodyParser.json());

// Etablir la connexion avec mongoDb
mongoose.connect('mongodb://localhost:27017/mern_crud_blog', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

const db = mongoose.connection;
db.on('error', console.error.bind(console, 'Erreur de connexion avec MongoDB:'));
db.once('open', () => {
  console.log('Connexion à MongoDB réussie');
});


// nous ajouterons des routes ici à l'avenir .....
// Avance pour en savoir plus


// Création du schéma étudiants
const Schema = mongoose.Schema;
const StudentSchema = new Schema({
  name: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true },
}, { timestamps: true });

// Création du Schéma projets
const ProjectSchema = new Schema({
  name: { type: String, required: true },
  description: { type: String, required: true },
  price: { type: Number, required: true },
}, { timestamps: true });

const Student = mongoose.model('Student', StudentSchema);
const Project = mongoose.model('Project', ProjectSchema);



app.listen(port, () => {
  console.log(`Le Serveur écoute sur le port ${port}`);
});

Enter fullscreen mode Exit fullscreen mode

Etape3: Implémenter le frontend (React.js et Tailwind pour le style)

  1. Dans le dossier client, créez un nouveau fichier nommé index.js et ajoutez le code suivant :

Assurez vous d'avoir installer Tailwind dans votre projet


// client/src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// Si tu veux commencer à mesurer les performances de ton application, passe une fonction
// pour enregistrer les résultats (par exemple : reportWebVitals(console.log))
// ou envoie-les à un point d'analyse. Apprends-en plus : https://bit.ly/CRA-vitals
reportWebVitals();

Enter fullscreen mode Exit fullscreen mode
  1. Créez un nouveau fichier nommé App.jsx dans le même répertoire et ajoutez le code suivant :

// client/src/App.jsx
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { BrowserRouter as Router, Route, Link, Routes } from 'react-router-dom';
import StudentList from './components/StudentList';
import ProjectList from './components/ProjectList';
import AddEditProject from './components/AddEditProject';
import AddEditStudent from './components/AddEditStudent';
import Home from './components/Home';

const App = () => {
  // Hooks d'état et d'effet
  const [Students, setStudents] = useState([]);
  const [Projects, setProjects] = useState([]);
  axios.defaults.baseURL = `http://localhost:5000`

  useEffect(() => {
    fetchStudents();
    fetchProjects();
  }, []);

  //Récupération de tous les étudiants dans la base de données
  const fetchStudents = async () => {
    try {
      const response = await axios.get('/api/Students');
      setStudents(response.data.data);
      console.log(response);
    } catch (error) {
      console.error('Error fetching Students:', error);
    }
  };

  //Récupération de tous les projets dans la base de données
  const fetchProjects = async () => {
    try {
      const response = await axios.get('/api/Projects');
      setProjects(response.data.data);
    } catch (error) {
      console.error('Error fetching Projects:', error);
    }
  };
  // Suppression d'un étudiant
  const deleteStudent = async (id) => {
    try {
      await axios.delete(`/api/Students/${id}`);
      fetchStudents(); // Fetch Students after deleting a Student
    } catch (error) {
      console.error('Error deleting Student:', error);
    }
  };
  // Suppression d'un projet
  const deleteProject = async (id) => {
    try {
      await axios.delete(`/api/Projects/${id}`);
      fetchProjects(); // Fetch Projects after deleting a Project
    } catch (error) {
      console.error('Error deleting Project:', error);
    }
  };

  return (
    <div className="mx-auto app h-[100vh]">
      <Router>
        <div className='flex flex-row bg-black py-4 px-4 justify-between align-middle items-center'>
          {/** Header */}
          <div>
            <h1 className="text-3xl font-bold text-white">Inscription PhD Géologie Numérique</h1>
            <small className="text-1xl font-bold text-white">MERN Stack CRUD Application</small>
          </div>

          <div className="flex">
            <div className="mr-4">
              <Link to="/" className="hover:bg-blue-500 rounded-2xl text-white px-2 py-1 rounded">
                Accuel
              </Link>
            </div>
            <div className="mr-4">
              <Link to="/Students" className="hover:bg-blue-500 rounded-2xl text-white px-2 py-1 rounded">
                Etudiants
              </Link>
            </div>
            <div className='mr-4'>
              <Link to="/Projects" className="hover:bg-blue-500 rounded-2xl text-white px-2 py-1 rounded">
                Projects
              </Link>
            </div>
          </div>
        </div>


        <div className=" w-[100%] h-[100%] flex mx-auto w-1/2 place-self-center place-content-center self-center ">

          <div className="flex flex-col bg-gray-600 pt-[2.5rem] w-[18rem]">


            <Link to="/" className="text-xl font-bold text-white">
              <div className={"pl-[2.5rem] hover:bg-blue-500 pt-[1rem] pb-[1rem] m-[5px] rounded-2xl"}>
                Accuel
              </div>
            </Link>


            <Link to="/Students" className="text-xl font-bold text-white">
              <div className="pl-[2.5rem] hover:bg-blue-500 pt-[1rem] pb-[1rem] m-[5px] rounded-2xl">
                Liste des étudiants
              </div>
            </Link>

            <Link to="/Projects" className="text-xl font-bold text-white">
              <div className='pl-[2.5rem] hover:bg-blue-500 pt-[1rem] pb-[1rem] m-[5px] rounded-2xl'>
                Projet d'études
              </div>
            </Link>
          </div>

          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="/Students" element={<StudentList Students={Students} fetchStudents={fetchStudents} deleteStudent={deleteStudent} />} />
            <Route path="/Projects" element={<ProjectList Projects={Projects} fetchProjects={fetchProjects} deleteProject={deleteProject} />} />
            <Route path="/add-Project" element={<AddEditProject fetchProjects={fetchProjects} />} />
            <Route path="/add-Student" element={<AddEditStudent fetchStudents={fetchProjects} />} />
            <Route path="/edit-Project/:id" element={<AddEditProject fetchProjects={fetchProjects} />} />
            <Route path="/edit-Student/:id" element={<AddEditStudent fetchStudents={fetchProjects} />} />
          </Routes>
        </div>

      </Router>
    </div>
  );
};

export default App;


Enter fullscreen mode Exit fullscreen mode

Étape 4 : implémenter des routes backend pour les utilisateurs et les produits

  1. Dans le fichier server.js, ajoutez les routes suivantes pour les opérations CRUD des utilisateurs et des produits :

// server.js 
// ... (code précédent) 

//2. Routes pour les étudiants..............................
// Récupération de tous les utilisateurs
app.get('/api/Students', (req, res) => {
  Student.find().then(item => {
    console.log(item);
    res.status(200).json({ message: 'Item fetched successfully', data: item, });
  })
    .catch(err => {
      console.log(err);
      res.status(500).json({ message: 'Server error' });
    });
});

// récupérer un seul utilisateur
app.get('/api/Students/:id', (req, res) => {
  const { id } = req.params;
  Student.find({_id:id}).then(item => {
    console.log(item);
    res.status(200).json({ message: 'Item fetched successfully', data: item, });
  })
    .catch(err => {
      console.log(err);
      res.status(500).json({ message: 'Server error' });
    });
});

// créer un nouvel étudiant
app.post('/api/Students', (req, res) => {
  const newStudent = new Student(req.body);
  console.log(newStudent);
  newStudent.save().then(item => {
    console.log(item);
    res.status(201).json({ message: 'Item added successfully' });
  })
    .catch(err => {
      console.log(err);
      res.status(500).json({ message: 'Server error' });
    });
});

// Mettre à jour (modifier)le nouvel étudiant
app.put('/api/Students/:id', (req, res) => {
  const { id } = req.params;
  Student.findByIdAndUpdate(id, req.body, { new: true }).then(item => {
    console.log(item);
    res.status(203).json({ message: 'Item Fetched Successfully', data:item });
  })
    .catch(err => {
      console.log(err);
      res.status(500).json({ message: 'Server error' });
    });
});

// Supprimer un étudiant
app.delete('/api/Students/:id', (req, res) => {
  const { id } = req.params;
  Student.findByIdAndRemove(id).then(item => {
    console.log(item);
    res.status(203).json({ message: 'Item Fetched Successfully', data:item });
  })
    .catch(err => {
      console.log(err);
      res.status(500).json({ message: 'Server error' });
    });
});

// 3. Routes pour les projets................................
// Récupération de tous les projets
app.get('/api/Projects', (req, res) => {
  Project.find().then(item => {
    console.log(item);
    res.status(201).json({ message: 'Projects Fetched Successfully!', data: item });
  })
    .catch(err => {
      console.log(err);
      res.status(500).json({ message: 'Server error' });
    });
});

// Récupération d'un seul projet
app.get('/api/Projects/:id', (req, res) => {
  const { id } = req.params;
  Project.find({_id:id}).then(item => {
    console.log(item);
    res.status(200).json({ message: 'Item fetched successfully', data: item, });
  })
    .catch(err => {
      console.log(err);
      res.status(500).json({ message: 'Server error' });
    });
});

// Création d'un nouveau projet
app.post('/api/Projects', (req, res) => {
  const newProject = new Project(req.body);
  newProject.save().then(item => {
    console.log(item);
    res.status(201).json({ message: 'Item added successfully' });
  })
    .catch(err => {
      console.log(err);
      res.status(500).json({ message: 'Server error' });
    });
});

// Mettre à jour (modifier) un projet
app.put('/api/Projects/:id', (req, res) => {
  const { id } = req.params;
  Project.findByIdAndUpdate(id, req.body, { new: true }).then(item => {
    console.log(item);
    res.status(203).json({ message: 'Item Fetched Successfully', data:item });
  })
    .catch(err => {
      console.log(err);
      res.status(500).json({ message: 'Server error' });
    });
});

// Supprimet un projet
app.delete('/api/Projects/:id', (req, res) => {
  const { id } = req.params;
  Project.findByIdAndRemove(id).then(item => {
    res.status(203).json({ message: 'Deleted Successfully' });
  })
    .catch(err => {
      console.log(err);
      res.status(500).json({ message: 'Server error' });
    });
});

// ... (code restant)


Enter fullscreen mode Exit fullscreen mode

Étape 5 : implémenter des composants frontend pour les utilisateurs et les produits

  1. Dans le répertoire client/src/components, créez un fichier nommés Home.jsx et ajoutez le code suivant :

// client/src/components/UserList.js
import React, { useEffect } from 'react';

const Home = () => {

    return (
        <div className='mt-10 flex flex-col mx-auto w-[70%]'>

            <div>
                <h1 className="text-[3rem] font-bold mb-2">Inscription PhD Géologie Numérique</h1>
                <h2 className="text-xl font-bold mb-2">Aprennez l'approche numérique de la géologie de terrain</h2>
                <p>Pour vous inscrire au programme de formation, vous devez fournir vos infromations proposer un projet de recherche.</p>
                <br />
                <div className=''>
                <img className='w-[25rem]' src="https://www.researchgate.net/profile/Remi-Valois/publication/278637347/figure/fig33/AS:332216954572802@1456218102119/Modele-numerique-de-terrain-avec-une-coupe-geologique-du-secteur-central-du-Causse-de.png" alt="" />
                </div>
                <br />
                <p>Pour plus d'information contactez cliquez <a className='text-blue-500' href='https://ger-cub.github.io/portfoliogerard/'>ici.</a></p>
                <br />
                <h1 className="text-[.6rem] font-[200] mb-2">MERN Stack CRUD Application Demostration ©Gerard-Mai/2024</h1>
            </div>

        </div>
    );
};

export default Home;


Enter fullscreen mode Exit fullscreen mode
  1. Dans le répertoire client/src/components, créez deux fichiers nommés StudentList.jsx, ProjectList.jsx et ajoutez le code suivant :

// client/src/components/StudentList.jsx
// client/src/components/StudentList.js
import React, { useEffect } from 'react';
import { Link, useSearchParams, useNavigate } from 'react-router-dom';

const StudentList = ({ Students, deleteStudent, fetchStudents }) => {
  const navigate = useNavigate();

  const editStudent = (id) => {
    navigate(`/edit-Student/${id}`);
  }

  useEffect(() => {
    fetchStudents()
  }, [])
  return (
    <div className=' mt-10 flex flex-col mx-auto w-[70%] overflow-y-auto'>
      <div className='justify-between flex'>
        <h2 className="text-xl font-bold mb-2">Liste des étudiants</h2>
        <Link to="/add-Student" className="bg-blue-500 text-white px-2 py-1 rounded">
          Ajouter un étudiant
        </Link>
      </div>
      <table className="table-auto mt-10 w-full">
        <thead>
          <tr>
            <th className="px-4 border py-2">Noms</th>
            <th className="px-4 border py-2">Adresses mails</th>
            <th className="px-4 border py-2">Actions</th>
          </tr>
        </thead>
        <tbody>
          {Students?.length
            ?
            Students.map((Student) => (
              <tr key={Student._id}>
                <td className="border px-4 py-2 text-center">{Student.name}</td>
                <td className="border px-4 py-2 text-center">{Student.email}</td>
                <td className="border px-4 py-2 flex flex-nowrap justify-center">
                  <button
                    className="bg-green-500 text-white px-2 py-1 rounded"
                    onClick={() => editStudent(Student._id)}
                  >
                    Modifier
                  </button>
                  <button
                    className="bg-red-500 ms-2 text-white px-2 py-1 rounded"
                    onClick={() => deleteStudent(Student._id)}
                  >
                    Supprimer
                  </button>

                </td>
              </tr>
            ))
            :
            <td className="border px-4 py-2 text-center" rowSpan={10} colSpan={10}>La liste est encore vide</td>

          }
        </tbody>
      </table>
    </div>
  );
};

export default StudentList;


Enter fullscreen mode Exit fullscreen mode

// client/src/components/ProjetList.jsx 
// client/src/components/ProjectList.js
import React, { useEffect } from 'react';
import { Link, useNavigate } from 'react-router-dom';

const ProjectList = ({ Projects, deleteProject, fetchProjects }) => {
  const navigate = useNavigate();

  const editProject = (id) => {
    navigate(`/edit-Project/${id}`);
  }
  useEffect(() => {
    fetchProjects();
  }, [])
  return (
    <div className='mt-10 flex flex-col mx-auto w-[70%] max-h-[80vh] overflow-y-auto'>
      <div className='justify-between flex'>
        <h2 className="text-xl font-bold mb-2">Liste des projets</h2>
        <Link to="/add-Project" className="bg-blue-500 text-white px-2 py-1 rounded">
          Ajouter un projet
        </Link>
      </div>
      <table className="table-auto mt-10 w-full">
        <thead>
          <tr>
            <th className="px-4 border  py-2">Noms</th>
            <th className="px-4 border  py-2">Description</th>
            <th className="px-4 border  py-2">Coût</th>
            <th className="px-4 border  py-2">Actions</th>
          </tr>
        </thead>
        <tbody>
          {

          Projects?.length ?
            Projects.map((Project) => (
              <tr key={Project._id}>
                <td className="border px-4 py-2 text-center">{Project.name}</td>
                <td className="border px-4 py-2 text-center">{Project.description}</td>
                <td className="border px-4 py-2 text-center">${Project.price}</td>
                <td className="border px-4 py-2 flex flex-nowrap justify-center">
                <button
                    className="bg-green-500 text-white px-2 py-1 rounded"
                    onClick={() => editProject(Project._id)}
                  >
                    Modifier
                  </button>
                  <button
                    className="bg-red-500 text-white px-2 ms-2 py-1 rounded"
                    onClick={() => deleteProject(Project._id)}
                  >
                    Supprimer
                  </button>
                </td>
              </tr>
            )) :
            <td className="border px-4 py-2 text-center" rowSpan={10} colSpan={10}>La liste est encore vide</td>

          }
        </tbody>
      </table>
    </div>
  );
};

export default ProjectList;


Enter fullscreen mode Exit fullscreen mode
  1. Dans le client/src/componentsrépertoire, créez deux fichiers nommés AddEditStudent.jsx et AddEditProject.jsx, et ajoutez le code suivant :

// client/src/pages/AddEditProject.js
// client/src/pages/AddEditProject.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { useNavigate, useParams } from 'react-router-dom';

const AddEditProject = ({ fetchProjects = null }) => {
  const navigate = useNavigate();
  const { id } = useParams();
  const [name, setName] = useState('');
  const [description, setDescription] = useState('');
  const [price, setPrice] = useState('');

  useEffect(() => {
    if (id) {
      fetchProject();
    }
  }, [id]);

  const fetchProject = async () => {
    try {
      const response = await axios.get(`/api/Projects/${id}`);
      setName(response.data.data[0].name);
      setDescription(response.data.data[0].description);
      setPrice(response.data.data[0].price);
    } catch (error) {
      console.error('Error fetching Project:', error);
    }
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    const newProject = { name, description, price: Number(price) };

    if (id) {
      try {
        await axios.put(`/api/Projects/${id}`, newProject);
        navigate('/Projects');
      } catch (error) {
        console.error('Error updating Project:', error);
      }
    } else {
      try {
        await axios.post('/api/Projects', newProject);
        fetchProjects(); // Fetch Projects after adding a new Project
        navigate('/Projects');
      } catch (error) {
        console.error('Error adding Project:', error);
      }
    }



  };

  // Compteur des mots

  const compterMots = () => {
    const mots = description.split(' ');
    return mots.length - 1;
  };

  return (
    <div className='w-[85%] p-[5rem]'>
      <h2 className="text-xl font-bold mb-2">{id ? 'Ajoutez votre' : 'Modifiez votre'} Projet</h2>
      <form onSubmit={compterMots() <= 450 && handleSubmit}>
        <div className="mb-4">
          <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="name">
            Nom complet
          </label>
          <input
            type="text"
            id="name"
            name="name"
            value={name}
            placeholder='Nom Postnom Prenom'
            onChange={(e) => setName(e.target.value)}
            required
            className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
          />
        </div>
        <div className="mb-4">
          <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="description">
            Bref description de votre Projet de recherche / Sujet, Problèmatique, Objectifs, Méthodologies et resultat attendus / 450 mots max
          </label>
          <textarea
            id="description"
            name="description"
            value={description}
            onChange={(e) => setDescription(e.target.value)}
            required
            className="shadow appearance-none border h-[15rem] rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
          />
          <small className={compterMots() < 450 ? 'text-green-500 text-justify' : 'text-red-500 text-justify'}>{compterMots()} mots.</small>
        </div>
        <div className="mb-4">
          <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="price">
            Coût estimé en $
          </label>
          <input
            type="number"
            id="price"
            name="price"
            value={price}
            onChange={(e) => setPrice(e.target.value)}
            required
            className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
          />
        </div>
        <div>
          <button
            type="submit"
            className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
          >
            Enregister
          </button>
        </div>
      </form>
    </div>
  );
};

export default AddEditProject;


Enter fullscreen mode Exit fullscreen mode

A ce stade votre application devrait ressemblé à ceci :

Image description


// client/src/pages/AddEditStudent.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { useNavigate,useSearchParams, useParams } from 'react-router-dom';

const AddEditStudent = ({ fetchStudents }) => {
  const navigate = useNavigate();

  const { id } = useParams();
  const [name, setname] = useState('');
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');


  useEffect(() => {
    if (id) {
      console.log('here');
      fetchStudent();
    }
  }, [id]);

  const fetchStudent = async () => {
    try {
      const response = await axios.get(`/api/Students/${id}`);
      setname(response.data.data[0].name);
      setEmail(response.data.data[0].email);
      setPassword(response.data.data[0].password);
    } catch (error) {
      console.error('Error fetching Student:', error);
    }
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    const newStudent = { name, email, password };

    if (id) {
      try {
        await axios.put(`/api/Students/${id}`, newStudent);
        navigate('/Students');
      } catch (error) {
        console.error('Error updating Student:', error);
      }
    } else {
      try {
        await axios.post('/api/Students', newStudent);
        fetchStudents(); // Fetch Students after adding a new Student
        navigate('/Students');
      } catch (error) {
        console.error('Error adding Student:', error);
      }
    }
  };

  return (
    <div className='w-[85%] p-[5rem]'>
      <h2 className="text-xl font-bold mb-2"> {id ? 'Modifier' : 'Ajouter'} l'étudiant</h2>
      <form onSubmit={handleSubmit} className='w-[70%]'>
        <div className="mb-4">
          <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="name">
            Nom
          </label>
          <input
            type="text"
            id="name"
            name="name"
            value={name}
            onChange={(e) => setname(e.target.value)}
            required
            className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
          />
        </div>
        <div className="mb-4">
          <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="email">
            Adresse mail
          </label>
          <input
            type="email"
            id="email"
            name="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            required
            className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
          />
        </div>
        <div className="mb-4">
          <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="email">
            Mot de passe
          </label>
          <input
            type="password"
            id="password"
            name="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            required
            className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
          />
        </div>
        <div>
          <button
            type="submit"
            className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
          >
            Enregistrer
          </button>
        </div>
      </form>
    </div>
  );
};

export default AddEditStudent;


Enter fullscreen mode Exit fullscreen mode

Image description

Dans le fichier client/src/App.jsx, vous avez déjà importé les composants StudentListet ProjectList pour les afficher dans le Appcomposant, extrayez à nouveau le code.

Étape 6 : tester l'application

Si vous êtes sous Windows ou Mac, vous pouvez utiliser l'interface graphique pour démarrer le serveur MongoDb, sinon sous Linux, vous pouvez utiliser mongod la commande pour exécuter le service.

  1. Ouvrez un nouveau terminal et démarrez le serveur MongoDB :
mongod
Enter fullscreen mode Exit fullscreen mode
  1. Dans un autre terminal, démarrez le serveur Node.js :
serveur de nœud.js
Enter fullscreen mode Exit fullscreen mode
  1. Dans un troisième terminal, accédez au client répertoire et démarrez le serveur de développement React :
client cd
 démarrage npm
Enter fullscreen mode Exit fullscreen mode
  1. Ouvrez votre navigateur Web et accédez http://localhost:3000 à l'application d'Inscription MERN Stack CRUD Application.

Pour la référence GitHub

https://github.com/Ger-Cub/inscription-phd-mern-crud-app
Enter fullscreen mode Exit fullscreen mode

Deploy a MERN STACK app on Render platform in 2024
(https://www.youtube.com/watch?v=ZsFwpjFmpFQ)

Choses à ne jamais oublier :

Adoptez la documentation comme boussole pour plus de clarté et de progrès.
Nourrissez un esprit curieux en vous demandant : « Qu’ai-je fait et pourquoi l’ai-je fait ? » à chaque étape.
Pratiquez la pleine conscience et restez concentré pour exceller dans n’importe quelle entreprise.
L'amélioration continue est un voyage, et même avec un dépôt GitHub minutieusement testé et à jour, soyez ouvert à tout commentaire pour améliorer davantage le code.

Merci d'avoir lu jusqu'au bout. Veuillez envisager de suivre l’écrivain et cette publication. Visitez Stackademic pour en savoir plus sur la façon dont nous démocratisons l’enseignement gratuit de la programmation dans le monde.

Top comments (0)