/Tutorial-App

CRUD operations with axios in React

Primary LanguageJavaScript

Tutorial App (CRUD Operations with Axios)

πŸ‘‰ Click here to see on browser

Tutorial app


What's used in this app ? How use third party libraries Author
useEfect() Hook componentDidUpdate() Take a look at my portfolio
useState() Hook Visit me on Linkedin
CRUD OPERATIONS with axios API npm i/yarn add axios
react-events
Bootstrap npm i / yarn add bootstrap
React-icons npm i / yarn add react-icons
props-drilling
Semantic-Commits
Deploy with Vercel
API fullstack.clarusway

How To Run This Project πŸš€


πŸ’» Install React πŸ‘‡

yarn create react-app .  or npx create-react-app .

πŸ’» Install Sass πŸ‘‡

yarn add sass  or npm i sass

πŸ”΄ Delete these files and delete the importsπŸ‘‡

- App.test.js
- reportWebVitals.js
- setupTests.js
- favicon.ico
- logo192.png
- logo512.png
- manifest.json
- robots.txt

πŸ’» Start the project πŸ‘‡

yarn start or npm start

OR

  • Clone the Repo

    git clone
  • Install NPM packages

    npm install or yarn
  • Run the project

    npm start or yarn start
  • Open the project on your browser

    http://localhost:3000/
  • Enjoy! πŸŽ‰


Project Skeleton

 Tutorial App(folder)
|
|----public (folder)
β”‚     └── index.html
|----src (folder)
|    |--- components (folder)
β”‚    β”‚       β”œβ”€β”€ AddTutorial.jsx
β”‚    β”‚       β”œβ”€β”€ EditTutorial.jsx
β”‚    β”‚       β”œβ”€β”€ TutorialList.jsx
β”‚    β”‚
β”‚    β”‚
β”‚    |--- pages (folder)
|    |      β”œβ”€β”€ Home.jsx
|    |
β”‚    β”œ--- App.js
β”‚    |--- index.js
β”‚
β”‚
|-- .gitignore
|── package-lock.json
β”œβ”€β”€ package.json
|── README.md
|── yarn.lock



At the end of the project, the following topics are to be covered;

  • CRUD(READ-GET with axios)useEffect() (componentDidUpdate() ) & useState() & onChange, onSubmit Events

   import { useEffect, useState } from "react";
   import AddTutorial from "../components/AddTutorial";
   import TutorialList from "../components/TutorialList";
   import axios from "axios";
   
   const Home = () => {
       const [tutorials, setTutorials] = useState([]);
   
       const getTutorials = async () => {
           const BASE_URL =
               "https://tutorial-api.fullstack.clarusway.com/tutorials/";
           try {
               // const res = await axios(BASE_URL)
               // setTutorials(res.data)
               const { data } = await axios(BASE_URL);
               setTutorials(data);
           } catch (error) {
               console.log(error);
           }
       };
   
       console.log(tutorials);
   
       //? Mount asamasinda api'ye istek atiyoruz
       useEffect(() => {
           getTutorials();
       }, []);
   
       return (
           <>
               <AddTutorial getTutorials={getTutorials} />
               <TutorialList tutorials={tutorials} getTutorials={getTutorials} />
           </>
       );
   };
   
   export default Home;
    
  • CRUD(CREATE-POST with axios)

      import { useState } from "react";
      import axios from "axios";
    
     const AddTutorial = ({ getTutorials }) => {
        const [title, setTitle] = useState("");
        const [description, setDescription] = useState("");
    
    const handleSubmit = (e) => {
        e.preventDefault();
        const newTutor = { title: title, description: description };
        console.log(newTutor);
        postTutorial(newTutor);
    
        setTitle("");
        setDescription("");
    };
    
    const postTutorial = async (newTutor) => {
        const BASE_URL =
            "https://tutorial-api.fullstack.clarusway.com/tutorials/";
        try {
            const res = await axios.post(BASE_URL, newTutor);
            console.log(res);
        } catch (error) {
            console.log(error);
        }
    
        //? Tum tutorial'lari iste ve state'i guncelle
        getTutorials();
    };
    
    return (
        <div className="container text-center mt-4">
            <h1 className="display-6 text-danger">Add Your Tutorial</h1>
            <form onSubmit={handleSubmit}>
                <div className="mb-3">
                    <label htmlFor="title" className="form-label">
                        Title
                    </label>
                    <input
                        type="text"
                        className="form-control"
                        id="title"
                        placeholder="Enter your title"
                        value={title}
                        onChange={(e) => setTitle(e.target.value)}
                        required
                    />
                </div>
                <div className="mb-3">
                    <label htmlFor="desc" className="form-label">
                        Description
                    </label>
                    <input
                        type="text"
                        className="form-control"
                        id="desc"
                        placeholder="Enter your Description"
                        value={description}
                        onChange={(e) => setDescription(e.target.value)}
                        required
                    />
                </div>
                <button type="submit" className="btn btn-danger mb-4">
                    Submit
                </button>
            </form>
        </div>
    );
    };
    
    export default AddTutorial;
    
       
  • CRUD(UPDATE-PUT with axios)useEffect() (componentDidUpdate() ) & useState() & onChange, onSubmit Events

       import axios from "axios";
       import { useEffect, useState } from "react";
       
       const EditTutorial = ({ editItem, getTutorials }) => {
           console.log(editItem);
       
           const { id, description: oldDescription, title: oldTitle } = editItem;
           console.log("old", oldTitle);
           console.log("old", oldDescription);
           //? https://react.dev/reference/react/useState#usestate
           //! State degiskeninin degeri, 1.render ile initialState
           //! parametresinin ilk degerini alir. Dolayisiyle bu durumda
           //! prop'tan gelen ilk deger state'e aktarilir.
           //! Sonradan degisen props degerleri useState'e aktarilmaz.
           //! Eger props'tan gelen degerleri her degisimde useState'e
           //! aktarmak istersek useEffect hook'unu componentDidUpdate
           //! gibi kullanabiriz.
           const [title, setTitle] = useState(oldTitle);
           const [description, setDescription] = useState(oldDescription);
       
           //? componentDidUpdate
           useEffect(() => {
               setTitle(oldTitle);
               setDescription(oldDescription);
               //? oldTitle veya oldDescriptiion her degistiginde local title ve description state'lerimizi guncelliyoruz.
           }, [oldTitle, oldDescription]);
       
           console.log(title); //ilk render da undefined
           console.log(description);
       
           const editTutor = async (tutor) => {
               const BASE_URL =
                   "https://tutorial-api.fullstack.clarusway.com/tutorials";
       
               try {
                   await axios.put(`${BASE_URL}/${id}/`, tutor);
               } catch (error) {
                   console.log(error);
               }
               getTutorials();
           };
           const handleSubmit = (e) => {
             e.preventDefault();
            
             editTutor({ title, description });
             // !yada objeyi degiskene atayip parametre olarak gΓΆnderebiliriz
             //  const tutor = {
             //      title,
             //      description,
             //  };
             //  editTutor(tutor);
           };
       
           return (
               <div
                   className="modal fade"
                   id="open-modal"
                   tabIndex={-1}
                   aria-labelledby="exampleModalLabel"
                   aria-hidden="true"
               >
                   <div className="modal-dialog">
                       <div className="modal-content">
                           <div className="modal-header">
                               <h1
                                   className="modal-title text-danger fs-5"
                                   id="exampleModalLabel"
                               >
                                   Edit Tutorial
                               </h1>
                               <button
                                   type="button"
                                   className="btn-close"
                                   data-bs-dismiss="modal"
                                   aria-label="Close"
                                   onClick={() => {
                                       setDescription("");
                                       setTitle("");
                                   }}
                               />
                           </div>
                           <div className="modal-body">
                               <form onSubmit={handleSubmit}>
                                   <div className="mb-3">
                                       <label htmlFor="title" className="form-label">
                                           Title
                                       </label>
                                       <input
                                           type="text"
                                           className="form-control"
                                           id="title"
                                           placeholder="Enter your title"
                                           value={title || ""}
                                           onChange={(e) => setTitle(e.target.value)}
                                           required
                                       />
                                   </div>
                                   <div className="mb-3">
                                       <label htmlFor="desc" className="form-label">
                                           Description
                                       </label>
                                       <input
                                           type="text"
                                           className="form-control"
                                           id="desc"
                                           placeholder="Enter your Description"
                                           value={description || ""}
                                           onChange={(e) =>
                                               setDescription(e.target.value)
                                           }
                                           required
                                       />
                                   </div>
       
                                   <div className="text-end">
                                       <button
                                           type="submit"
                                           className="btn btn-danger"
                                           data-bs-dismiss="modal"
                                       >
                                           Submit
                                       </button>
                                   </div>
                               </form>
                           </div>
                       </div>
                   </div>
               </div>
           );
       };
       
       export default EditTutorial;

   
  • CRUD(DELETE-DELETE with Axios)

            import { FaEdit } from "react-icons/fa";
            import { AiFillDelete } from "react-icons/ai";
            import axios from "axios";
            import EditTutorial from "./EditTutorial";
            import { useState } from "react";
            
            const TutorialList = ({ tutorials, getTutorials }) => {
                const [editItem, setEditItem] = useState("");
        
            console.log(editItem);
            // const tutorials = [
            //   {
            //     id: 1,
            //     title: "JS",
            //     description: "JS is a programming language",
            //   },
            //   {
            //     id: 2,
            //     title: "React",
            //     description: "JS library for UI design",
            //   },
            //   {
            //     id: 3,
            //     title: "VUE",
            //     description: "JS library for UI design",
            //   },
            // ]
            const BASE_URL = "https://tutorial-api.fullstack.clarusway.com/tutorials";
        
            const handleDelete = async (id) => {
                try {
                    await axios.delete(`${BASE_URL}/${id}/`);
                } catch (error) {
                    console.log(error);
                }
                getTutorials();
            };
        
            // const editTutor = async (tutor) => {
            //   try {
            //     await axios.put(`${BASE_URL}/${tutor.id}/`, tutor)
            //   } catch (error) {
            //     console.log(error)
            //   }
            //   getTutorials()
            // }
        
            return (
                <div className="container mt-4">
                    <table className="table table-striped">
                        <thead>
                            <tr>
                                <th scope="col">#id</th>
                                <th scope="col">Title</th>
                                <th scope="col">Description</th>
                                <th scope="col" className="text-center">
                                    Edit
                                </th>
                            </tr>
                        </thead>
                        <tbody>
                            {tutorials?.map((item) => {
                                const { id, title, description } = item;
                                return (
                                    <tr key={id}>
                                        <th>{id}</th>
                                        <td>{title}</td>
                                        <td>{description}</td>
                                        <td className="text-center text-nowrap">
                                            <FaEdit
                                                size={20}
                                                type="button"
                                                className="me-2 text-warning"
                                                data-bs-toggle="modal"
                                                data-bs-target="#open-modal"
                                                // onClick={() =>
                                                //   editTutor({
                                                //     id: 1934,
                                                //     title: "REACT",
                                                //     description: "JS Library",
                                                //   })
                                                // }
        
                                                onClick={() => setEditItem(item)}
                                            />
                                            <AiFillDelete
                                                size={22}
                                                type="button"
                                                className="text-danger "
                                                onClick={() => handleDelete(id)}
                                            />
                                        </td>
                                    </tr>
                                );
                            })}
                        </tbody>
                    </table>
        
                    <EditTutorial editItem={editItem} getTutorials={getTutorials} />
                </div>
            );
        };
        
        export default TutorialList;
  • Bootstrap in React

    • js ΓΆzellikleri icin index.html de body nin en altina asagidaki script eklenmeli
    <script
       src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"
       integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz"
       crossorigin="anonymous"
     ></script>
    • css ΓΆzellikleri icin index.js ye eklenmeli
       import "bootstrap/dist/css/bootstrap.min.css";
  • Semantic Commit Messages See how a minor change to your commit message style can make you a better programmer.

    Format: ():

    is optional

    • Example
                feat: add hat wobble
        ^--^  ^------------^
        |     |
        |     +-> Summary in present tense.
        |
        +-------> Type: chore, docs, feat, fix, refactor, style, or test.
    
  • More Examples:

    • feat: (new feature for the user, not a new feature for build script)
    • fix: (bug fix for the user, not a fix to a build script)
    • docs: (changes to the documentation)
    • style: (formatting, missing semi colons, etc; no production code change)
    • refactor: (refactoring production code, eg. renaming a variable)
    • test: (adding missing tests, refactoring tests; no production code change)
    • chore: (updating grunt tasks etc; no production code change)

Feedback and Collaboration

I value your feedback and suggestions. If you have any comments, questions, or ideas for improvement regarding this project or any of my other projects, please don't hesitate to reach out. I'm always open to collaboration and welcome the opportunity to work on exciting projects together. Thank you for visiting my project. I hope you have a wonderful experience exploring it, and I look forward to connecting with you soon!

βŒ› Happy Coding ✍