Mern Social Network الجزء السادس

فهاد الجزء السادس من MERN social network غادي نكملوا ل projet ديالنا وندوزوا للجزء الخاص بإضافة routes وال menu ومنبعد غادي نشوفوا كيفاش نخليو المستخدم يتسجل و يدخل يعني ل connexion ول inscription.

نظرة سريعة بالفيديو


1- إضافة routes


باش نتحرك فل app خصني routes أول حاجة زيد les routes بل commande :

npm install react-router-dom

منبعد فل fichier App.js غادي نديرو تعديلات غادي نزيدو routes ديالنا لي فاش كندخل لكل واحد كنشوف component لي غادي نزيدوهم من بعد.

الكود ديال الملف بعد التعديل هو :

                                    
                                        import React from "react";
import Home from "./pages/Home";
import Navbar from "./components/Navbar";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import Register from "./pages/Register";
import Login from "./pages/Login";
import { useDispatch, connect } from "react-redux";
import { authCheck } from "./redux/actions/userActions";
import Users from "./pages/Users";
import Profile from "./pages/Profile";
import EditProfile from "./pages/EditProfile";

function App({ currentUser }) {
  const dispatch = useDispatch();

  React.useEffect(() => {
    dispatch(authCheck());
  }, [dispatch]);

  return (
    <BrowserRouter>
      <Navbar currentUser={currentUser && currentUser} />
      <Switch>
        <Route path="/" exact component={Home} />
        <Route path="/register" exact component={Register} />
        <Route path="/login" exact component={Login} />
        <Route path="/users" exact component={Users} />
        <Route path="/user/:userId" exact component={Profile} />
        <Route path="/user/edit/:userId" exact component={EditProfile} />
      </Switch>
    </BrowserRouter>
  );
}

const mapStateToProps = ({ user: { currentUser } }) => ({
  currentUser,
});

export default connect(mapStateToProps)(App);
                                    
                                

2- إضافة ل Menu


منبعد ما زدنا routes غادي نزيدو ل Menu

ف dossier src غادي تزيد dossier components لي فيه غادي تزيد fichier Navbar.js لي فيه غادي تكون ال Menu ديالنا.

الكود ديال الملف هو :

                                    
                                        import React from "react";
import { Link, useHistory } from "react-router-dom";
import { logout } from "../helpers/auth";

export default function Navbar({ currentUser }) {
  const history = useHistory();
  return (
    <nav className="navbar navbar-expand-lg navbar-light bg-light">
      <Link className="navbar-brand" to="/">
        React Social
      </Link>
      <button
        className="navbar-toggler"
        type="button"
        data-toggle="collapse"
        data-target="#navbarSupportedContent"
        aria-controls="navbarSupportedContent"
        aria-expanded="false"
        aria-label="Toggle navigation"
      >
        <span className="navbar-toggler-icon"></span>
      </button>

      <div className="collapse navbar-collapse" id="navbarSupportedContent">
        <ul className="navbar-nav mr-auto">
          <li className="nav-item active">
            <Link className="nav-link" to="/">
              Accueil <span className="sr-only">(current)</span>
            </Link>
          </li>
          <li className="nav-item">
            <Link className="nav-link" to="/users">
              Users
            </Link>
          </li>
          <li className="nav-item dropdown">
            <a
              className="nav-link dropdown-toggle"
              href="#"
              id="navbarDropdown"
              role="button"
              data-toggle="dropdown"
              aria-haspopup="true"
              aria-expanded="false"
            >
              Compte
            </a>
            <div className="dropdown-menu" aria-labelledby="navbarDropdown">
              {!currentUser ? (
                <>
                  <Link className="dropdown-item" to="/register">
                    Inscription
                  </Link>
                  <Link className="dropdown-item" to="/login">
                    Connexion
                  </Link>
                </>
              ) : (
                <>
                  <Link
                    className="dropdown-item"
                    to={`/user/${
                      currentUser && currentUser.user && currentUser.user._id
                    }`}
                  >
                    @{currentUser && currentUser.user.name}
                  </Link>
                  <Link
                    className="dropdown-item"
                    onClick={() => {
                      logout(() => {
                        history.push("/login");
                      });
                    }}
                    to="#"
                  >
                    Déconnexion
                  </Link>
                </>
              )}
            </div>
          </li>
        </ul>
      </div>
    </nav>
  );
}
                                    
                                

3- إضافة الملف auth.js


قبل مانزيدو login و register غادي تزيد dossier helpers ف src هاد dossier helpers زيد فيه fichier auth.js لي غادي يكونوا فيه des fonctions لي غادي نحتاجوا من بعد.

الكود ديال الملف هو :

                                      
                                        export const saveUserToLocalStorage = (jwt) => {
  localStorage.setItem("jwt", JSON.stringify(jwt));
};

export const isLogged = () => {
  if (localStorage.getItem("jwt")) {
    return JSON.parse(localStorage.getItem("jwt"));
  } else {
    return false;
  }
};

export const logout = (cb) => {
  localStorage.removeItem("jwt");
  document.cookie = "t=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/";
  cb();
};

export const checkAuth = (userId) => {
  return isLogged().user._id === userId;
};
                                      
                                    

4- إضافة ل inscription


دبا غادي ندوزو ل register ف dossier src زيد dossier pages فهاد dossier pages زيد fichier سميه register.js لي غادي تكون فيه الفورم ديال التسجيل ولي غادي تمكن المستخدم باش يتزاد فقاعدة البيانات.

الكود ديال الملف هو :

                                        
                                            import React from "react";
import { useDispatch, connect } from "react-redux";
import { createUser } from "../redux/actions/userActions";
import { Redirect } from "react-router-dom";

function Register({ userError, userSuccess }) {
  const [user, setUser] = React.useState({
    name: "",
    email: "",
    password: "",
  });
  const [error, setError] = React.useState(null);
  const [success, setSuccess] = React.useState(false);
  const dispatch = useDispatch();

  React.useEffect(() => {
    if (userError && userError !== null) {
      setError(userError);
    }
    if (userSuccess) {
      setSuccess(userSuccess);
      dispatch({ type: "TOGGLE_SUCCESS" });
    }
    return () => {
      dispatch({ type: "HIDE_USER_ERROR" });
    };
  }, [userError, userSuccess, dispatch]);

  function handleInputChange(event) {
    setError("");
    setUser({ ...user, [event.target.name]: event.target.value });
  }

  function showError() {
    return error && <div className="alert alert-danger">{error}</div>;
  }

  function redirectUser() {
    return success && <Redirect to="/login" />;
  }

  function handleFormSubmit(event) {
    event.preventDefault();
    dispatch(createUser(user));
  }

  return (
    <div className="container">
      <div className="row my-5">
        <div className="col-md-6 mx-auto">
          {showError()}
          {redirectUser()}
          <h3 className="card-title">Inscription</h3>
          <form onSubmit={handleFormSubmit} className="card p-2">
            <div className="form-group">
              <input
                type="text"
                name="name"
                placeholder="Nom & Prénom"
                value={user.name}
                required
                onChange={(event) => handleInputChange(event)}
                className="form-control"
              />
            </div>
            <div className="form-group">
              <input
                type="email"
                name="email"
                placeholder="Email"
                required
                value={user.email}
                onChange={(event) => handleInputChange(event)}
                className="form-control"
              />
            </div>
            <div className="form-group">
              <input
                type="password"
                name="password"
                placeholder="Mot de passe"
                required
                value={user.password}
                onChange={(event) => handleInputChange(event)}
                className="form-control"
              />
            </div>
            <div className="form-group">
              <button type="submit" className="btn btn-outline-primary">
                Valider
              </button>
            </div>
          </form>
        </div>
      </div>
    </div>
  );
}

const mapStateToProps = ({ user: { userError, userSuccess } }) => ({
  userError,
  userSuccess,
});

export default connect(mapStateToProps, null)(Register);
                                        
                                    

5- إضافة ل connexion


دبا غادي ندوزو ل login ف dossier pages زيد fichier سميه login.js لي غادي تكون فيه الفورم ديال ل connexion ولي غادي تمكن المستخدم باش يدخل ويزيد des teweets.

الكود ديال الملف هو :

                                        
                                            import React from "react";
import { useDispatch, connect } from "react-redux";
import { login } from "../redux/actions/userActions";
import { Redirect } from "react-router-dom";

function Login({ userError, userSuccess }) {
  const [user, setUser] = React.useState({
    email: "",
    password: "",
  });
  const [error, setError] = React.useState(null);
  const [success, setSuccess] = React.useState(false);
  const dispatch = useDispatch();

  React.useEffect(() => {
    if (userError && userError !== null) {
      setError(userError);
    }
    if (userSuccess) {
      setSuccess(userSuccess);
      dispatch({ type: "TOGGLE_SUCCESS" });
    }

    return () => {
      dispatch({ type: "HIDE_USER_ERROR" });
    };
  }, [userError, userSuccess, dispatch]);

  function handleInputChange(event) {
    setError("");
    setUser({ ...user, [event.target.name]: event.target.value });
  }

  function showError() {
    return error && <div className="alert alert-danger">{error}</div>;
  }

  function redirectUser() {
    return success && <Redirect to="/" />;
  }

  function handleFormSubmit(event) {
    event.preventDefault();
    dispatch(login(user));
  }

  return (
    <div className="container">
      <div className="row my-5">
        <div className="col-md-6 mx-auto">
          {showError()}
          {redirectUser()}
          <h3 className="card-title">Connexion</h3>
          <form onSubmit={handleFormSubmit} className="card p-2">
            <div className="form-group">
              <input
                type="email"
                name="email"
                placeholder="Email"
                required
                value={user.email}
                onChange={(event) => handleInputChange(event)}
                className="form-control"
              />
            </div>
            <div className="form-group">
              <input
                type="password"
                name="password"
                placeholder="Mot de passe"
                required
                value={user.password}
                onChange={(event) => handleInputChange(event)}
                className="form-control"
              />
            </div>
            <div className="form-group">
              <button type="submit" className="btn btn-outline-primary">
                Valider
              </button>
            </div>
          </form>
        </div>
      </div>
    </div>
  );
}

const mapStateToProps = ({ user: { userError, userSuccess } }) => ({
  userError,
  userSuccess,
});

export default connect(mapStateToProps, null)(Login);
                                        
                                    

كلمات مفاتيح :