Logo Universitas

Universitas ASA Indonesia

Program Studi: Teknologi Informasi

Mata Kuliah: Pengembangan Aplikasi Web Lanjut

SKS: 3 (2 teori, 1 praktikum)

Dosen Pengampu: Istiqomah Sumadikarta, S.T., M.Kom.

Beranda Mundur Maju

Pertemuan 10: Implementasi Halaman Pengguna #1

Membuat Component Header Web dan Footer Web


Setelah berhasil menyelesaikan materi untuk halaman admin, maka sekarang kita lanjutkan belajar dihalaman website depan. Seperti menampilkan data categories, places, sliders, maps dan lain-lain.

Pertama-tama kita akan membuat sebuah component untuk menampilkan header atau navbar dari website yang sedang kita kembangkan. Dimana header tersebut akan berisi beberapa informasi meliputi main menu, kolom pencarian dan button login.

Langkah 1 - Membuat Component Header Web

Silahkan buat folder baru dengan nama web di dalam folder src/components dan di dalam folder web silahkan buat file baru dengan nama Header.jsx, kemudian masukkan kode berikut ini di dalamnya.

//import react and hook
import React from "react";

//import component react bootstrap
import {
    Navbar,
    Container,
    Nav,
    NavDropdown,
} from 'react-bootstrap';

//import react router dom
import { Link } from "react-router-dom";

function WebHeader() {

    return (
        <React.Fragment>
            <Navbar collapseOnSelect expand="lg" className="navbar-custom shadow-sm" fixed="top">
                <Container>
                    <Navbar.Brand as={Link} to="/" className="fw-bold text-white"><i className="fa fa-map-marked-alt"></i> TRAVEL GIS</Navbar.Brand>
                    <Navbar.Toggle aria-controls="responsive-navbar-nav" />
                    <Navbar.Collapse id="responsive-navbar-nav">
                    <Nav className="me-auto">
                        <NavDropdown title={<span><i className="fa fa-list-ul"></i> CATEGORIES</span> } id="collasible-nav-dropdown" className="fw-bold text-white">
                        <NavDropdown.Divider />
                        <NavDropdown.Item as={Link} to="/posts/direction">LIHAT LAINNYA <i className="fa fa-long-arrow-alt-right"></i></NavDropdown.Item>
                        </NavDropdown>
                        <Nav.Link as={Link} to="/places" className="fw-bold text-white"><i className="fa fa-globe-asia"></i> PLACES</Nav.Link>
                        <Nav.Link as={Link} to="/maps" className="fw-bold text-white"><i className="fa fa-map"></i> MAPS</Nav.Link>
                    </Nav>
                    <Nav>
                        <Nav.Link className="fw-bold text-white me-4"><i className="fa fa-search"></i> SEARCH</Nav.Link>
                        <Link to="/admin/login" className="btn btn-md btn-light"><i className="fa fa-lock"></i> LOGIN</Link>
                    </Nav>
                    </Navbar.Collapse>
                </Container>
            </Navbar>
        </React.Fragment>
    );
}

export default WebHeader;

Dari penambahan kode di atas, pertama kita import React dari react.

//import react and hook
import React from "react";

Selanjutnya, kita import beberapa component dari React Bootstrap. Dimana component-component ini akan kita gunakan untuk membuat sebuah navbar dan dropdown.

//import component react bootstrap
import {
    Navbar,
    Container,
    Nav,
    NavDropdown,
} from 'react-bootstrap';

Kemudian kita import Provider Link dari React Router DOM.

//import react router dom
import { Link } from "react-router-dom";

Di dalam function component WebHeader kita buat konfigurasi untuk navbar-nya, dimana kita akan menambahkan sebuah menu dan dropdown menu. Kurang lebih seperti berikut ini contohnya.

<Nav className="me-auto">
     
     <NavDropdown title={<span><i className="fa fa-list-ul"></i> CATEGORIES</span> } id="collasible-nav-dropdown" className="fw-bold text-white">
     
     <NavDropdown.Divider />
     
     <NavDropdown.Item as={Link} to="/posts/direction">LIHAT LAINNYA <i className="fa fa-long-arrow-alt-right"></i></NavDropdown.Item>
     </NavDropdown>
     
     <Nav.Link as={Link} to="/places" className="fw-bold text-white"><i className="fa fa-globe-asia"></i> PLACES</Nav.Link>
     
     <Nav.Link as={Link} to="/maps" className="fw-bold text-white"><i className="fa fa-map"></i> MAPS</Nav.Link>
     
</Nav>

Langkah 2 - Membuat Component Footer Web

Setelah berhasil membuat component header, sekarang kita lanjutkan membuat component untuk footer. Silahkan buat file baru dengan nama Footer.jsx di dalam folder src/components/web, kemudian masukkan kode berikut ini di dalamnya.

//import react
import React from 'react';

function WebFooter() {

    return(
        <React.Fragment>
            <footer>
                <div className="footer_top">
                    <div className="footer_bg">
                        <div className="footer_bg_one"></div>
                        <div className="footer_bg_two"></div>
                    </div>
                </div>
            </footer>
        </React.Fragment>
    )
}

export default WebFooter;

Dari penambahan kode di atas, kita hanya menambahkan beberapa HTML untuk component footer.

Membuat Component Slider


Pada materi kali ini kita akan belajar membuat component slider, dimana component ini akan kita gunakan untuk menampilkan gambar-gambar slide yang biasanya ada pada sebuah halaman depan website. Disini kita akan belajar mengambil data gambar secara dinamis dari database melalui Rest API yang sudah kita buat di dalam Laravel.

Sekarang silahkan buat file baru dengan nama Slider.jsx di dalam folder src/components/web, kemudian masukkan kode berikut ini di dalamnya.

//import hook useState and useEffect from react
import React, { useState, useEffect } from "react";

//import component carousel
import { Carousel } from "react-bootstrap";

//import BASE URL API
import Api from "../../api";

function Slider() {

    //state sliders
    const [sliders, setSliders] = useState([]);

    //function "fetchDataSliders"
    const fetchDataSliders = async () => {

        //fetching Rest API "sliders"
        await Api.get('/api/web/sliders')
            .then((response) => {

                //set data to state
                setSliders(response.data.data);
            });
    }

    //hook
    useEffect(() => {

        //call function "fetchDataSliders"
        fetchDataSliders();

    }, []);

    return (
        <Carousel prevIcon={<i className="fa fa-chevron-left fa-lg carousel-custom text-dark shadow"></i>} nextIcon={<i className="fa fa-chevron-right fa-lg carousel-custom text-dark shadow"></i>}>
            {sliders.map((slider) => (
                <Carousel.Item key={slider.id}>
                    <img className="d-block w-100" src={slider.image} style={{ height: "500px", objectFit: "cover" }}  alt="First slide"/>
                </Carousel.Item>
            ))}
        </Carousel>
    )

}

export default Slider;

Dari penambahan kode di atas, pertama kita melakukan import 2 hook dari react, yaitu useState dan useEffect.

//import hook useState and useEffect from react
import React, { useState, useEffect } from "react";

Kemudian kita import component Corousel dari React Bootstrap. Component tersebut akan kita gunakan untuk membuat slider di dalam Bootstrap.

//import component carousel
import { Carousel } from "react-bootstrap";

Karena akan melakukan HTTP request ke server untuk mendapatkan data, maka kita perlu melakukan import konfigurasi API yang sudah kita buat sebelum-sebelumnya.

//import BASE URL API
import Api from "../../api";

Di dalam function component Slider, pertama-tama kita membuat sebuah state baru yang bernama sliders. State tersebut akan kita gunakan untuk menyimpan data response slider dari Rest API.

//state sliders
const [sliders, setSliders] = useState([]);

Setelah itu, kita membuat function baru yang bernama fetchDataSliders. Function ini akan kita gunakan untuk melakukan HTTP request ke server.

//function "fetchDataSliders"
const fetchDataSliders = async () => {

	//...
	
}

Di dalam function di atas, kita akan memanggil endpoint /api/web/sliders dengan method GET.

//fetching Rest API "sliders"
await Api.get('/api/web/sliders')

Jika berhasil, kita akan assign response data-nya ke dalam state sliders.

//set data to state
setSliders(response.data.data);

Selanjutnya, agar function fetchDataSliders dapat dijalankan pertama kali saat halaman diakses, maka kita perlu memanggilnya di dalam hook useEffect.

//hook
useEffect(() => {

    //call function "fetchDataSliders"
    fetchDataSliders();

}, []);

Dan setelah itu, kita tinggal melakukan perulangan di dalam JSX menggunakan fungsi bawaan dari JavaScript, yaitu map.

{sliders.map((slider) => (
    <Carousel.Item key={slider.id}>
        <img className="d-block w-100" src={slider.image} style={{ height: "500px", objectFit: "cover" }}  alt="First slide"/>
    </Carousel.Item>
))}

Membuat Layout Web


Setelah berhasil membuat beberapa components, seperti Header, Footer dan Slider. Maka sekarang kita akan lanjutkan membuat sebuah layout yang nantinya kita jadikan sebagai induk template untuk halaman web depan. Dimana kita akan memanggil beberapa component di atas di dalam layout ini, tujuannya agar kita tidak memanggil-manggil ulang component tersebut di halaman-halaman yang lainnya.

Silahkan buat file baru dengan nama Web.jsx di dalam folder src/layouts, kemudian masukkan kode berikut ini di dalamnya.

import React from "react";

//import component Header
import Header from "../components/web/Header";

//import component Footer
import Footer from "../components/web/Footer";

const LayoutWeb = ({ children }) => {
  return (
    <React.Fragment>
      <Header/>

        {children}

      <Footer />
    </React.Fragment>
  );
};

export default LayoutWeb;

Dari penambahan kode di atas, pertama kita import 2 component yang sudah kita buat sebelumnya, yaitu Header dan Footer.

//import component Header
import Header from "../components/web/Header";

//import component Footer
import Footer from "../components/web/Footer";

Setelah itu, di dalam return kita panggil component Header dan Footer tersebut. Dan untuk merender view/component yang meng-extends dari layout ini, kita bisa menggunakan sintaks seperti berikut ini :

{children}

Konfigurasi Route untuk Halaman Home


Pada materi kali ini, kita akan belajar membuat konfigurasi route untuk menampilkan halaman home. Di dalam halaman home, nanti kita akan gunakan untuk menampilkan beberapa informasi, seperti data sliders dan categories.

Seperti sebelumnya, sebelum kita melakukan konfigurasi sebuah route, maka kita perlu membuat sebuah view/component-nya terlebih dahulu.

Langkah 1 - Membuat View/Component Home

Sekarang silahkan buat folder baru dengan nama web di dalam folder src/pages dan di dalam folder web silahkan buat folder lagi dengan nama home, kemudian di dalam folder home silahkan buat file baru dengan nama Index.jsx dan masukkan kode berikut ini di dalamnya.

//import layout
import React from "react";

//import layout web
import LayoutWeb from "../../../layouts/Web";

function Home() {
  return (
    <React.Fragment>
      <LayoutWeb>
        <div className="container mt-5">
            <h1>Home</h1>
        </div>
      </LayoutWeb>
    </React.Fragment>
  );
}

export default Home;

Dari pernambahan kode di atas, pertama kita import React dari react.

//import layout
import React from "react";

Setelah itu, kita import layout web, ini akan kita gunakan sebagai induk layout dari halaman.

//import layout web
import LayoutWeb from "../../../layouts/Web";

Langkah 2 - Konfigurasi Route Home

Setelah berhasil membuat view/component untuk halaman home, maka sekarang kita lanjutkan membuat konfigurasi route-nya.

Silahkan buka file src/routes/routes.jsx, kemudian ubah semua kode-nya menjadi seperti berikut ini :

//import react router dom
import { Routes, Route } from "react-router-dom";

//=======================================================================
//ADMIN
//=======================================================================

//import view Login
import Login from '../pages/admin/Login.jsx';

//import component private routes
import PrivateRoute from "./PrivateRoutes";

//import view admin Dashboard
import Dashboard from '../pages/admin/dashboard/Index.jsx';

//import view admin categories Index
import CategoriesIndex from '../pages/admin/categories/Index.jsx';

//import view admin category Create
import CategoryCreate from '../pages/admin/categories/Create.jsx';

//import view admin category Edit
import CategoryEdit from '../pages/admin/categories/Edit.jsx';

//import view admin places Index
import PlacesIndex from '../pages/admin/places/Index.jsx';

//import view admin places Create
import PlaceCreate from '../pages/admin/places/Create.jsx';

//import view admin places Edit
import PlaceEdit from '../pages/admin/places/Edit.jsx';

//import view admin sliders Index
import SlidersIndex from '../pages/admin/sliders/Index.jsx';

//import view admin slider Create
import SliderCreate from '../pages/admin/sliders/Create.jsx';

//import view admin users Index
import UsersIndex from '../pages/admin/users/Index.jsx';

//import view admin user Create
import UserCreate from '../pages/admin/users/Create.jsx';

//import view admin user Edit
import UserEdit from '../pages/admin/users/Edit.jsx';

//=======================================================================
//WEB
//=======================================================================

//import view web Home
import Home from '../pages/web/home/Index.jsx';

function RoutesIndex() {
    return (
        <Routes>

            {/* route "/admin/login" */}
            <Route path="/admin/login" element={<Login />} />

            {/* private route "/admin/dashboard" */}
            <Route
                path="/admin/dashboard"
                element={
                        <PrivateRoute>
                            <Dashboard />
                        </PrivateRoute>
                }
            />

            {/* private route "/admin/categories" */}
            <Route
                path="/admin/categories"
                element={
                        <PrivateRoute>
                            <CategoriesIndex />
                        </PrivateRoute>
                }
            />

            {/* private route "/admin/categories/create" */}
            <Route
                path="/admin/categories/create"
                element={
                        <PrivateRoute>
                            <CategoryCreate />
                        </PrivateRoute>
                }
            />

            {/* private route "/admin/categories/edit/:id" */}
            <Route
                path="/admin/categories/edit/:id"
                element={
                        <PrivateRoute>
                            <CategoryEdit />
                        </PrivateRoute>
                }
            />

            {/* private route "/admin/places" */}
            <Route
                path="/admin/places"
                element={
                        <PrivateRoute>
                            <PlacesIndex />
                        </PrivateRoute>
                }
            />

            {/* private route "/admin/places/create" */}
            <Route
                path="/admin/places/create"
                element={
                        <PrivateRoute>
                            <PlaceCreate />
                        </PrivateRoute>
                }
            />

            {/* private route "/admin/places/edit/:id" */}
            <Route
                path="/admin/places/edit/:id"
                element={
                        <PrivateRoute>
                            <PlaceEdit />
                        </PrivateRoute>
                }
            />

            {/* private route "/admin/sliders" */}
            <Route
                path="/admin/sliders"
                element={
                        <PrivateRoute>
                            <SlidersIndex />
                        </PrivateRoute>
                }
            />

            {/* private route "/admin/sliders/create" */}
            <Route
                path="/admin/sliders/create"
                element={
                        <PrivateRoute>
                            <SliderCreate />
                        </PrivateRoute>
                }
            />

            {/* private route "/admin/users" */}
            <Route
                path="/admin/users"
                element={
                        <PrivateRoute>
                            <UsersIndex />
                        </PrivateRoute>
                }
            />

            {/* private route "/admin/users/create" */}
            <Route
                path="/admin/users/create"
                element={
                        <PrivateRoute>
                            <UserCreate />
                        </PrivateRoute>
                }
            />

            {/* private route "/admin/users/edit/:id" */}
            <Route
                path="/admin/users/edit/:id"
                element={
                        <PrivateRoute>
                            <UserEdit />
                        </PrivateRoute>
                }
            />

            {/* route "/" */}
            <Route path="/" element={<Home />} />


        </Routes>
    )
}

export default RoutesIndex

Dari perubahan kode di atas, pertama-tama kita import view/component home terlebih dahulu.

//import view web Home
import Home from '../pages/web/home/Index.jsx';

Setelah itu, kita buat konfigurasi route dengan path /. Yang artinya jika kita akses URL /, maka view/component home yang akan dijalankan.

Sekarang, silahkan reload / refresh halaman home atau ke URL berikut ini http://localhost:5173/, jika berhasil maka akan mendapatkan hasil seperti berikut ini :

Menampilkan Data Categories di Navbar


Jika kita perhatikan di navbar ada menu yang bernama CATEGORIES dengan jenis dropdown. Tapi kita belum menampilkan data categories tersebut di dalamnya. Oleh sebab itu pada materi kali ini kita akan belajar untuk menampilkan data categories dari database menggunakan Rest API di dalam navbar.

Sekarang, silahkan buka file src/components/web/Header.jsx, kemudian ubah semua kode-nya menjadi seperti berikut ini :

//import react and hook
import React, { useState, useEffect } from "react";

//import component react bootstrap
import {
    Navbar,
    Container,
    Nav,
    NavDropdown,
} from 'react-bootstrap';

//import react router dom
import { Link } from "react-router-dom";

//import BASE URL API
import Api from "../../api";

function WebHeader() {

    //state categories
    const [categories, setCategories] = useState([]);

    //function "fetchDataCategories"
    const fetchDataCategories = async () => {

        //fetching Rest API "categories"
        await Api.get('/api/web/categories')
            .then((response) => {

                //set data to state
                setCategories(response.data.data);
            });
    }

    //hook
    useEffect(() => {

        //call function "fetchDataCategories"
        fetchDataCategories();

        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    return (
        <React.Fragment>
            <Navbar collapseOnSelect expand="lg" className="navbar-custom shadow-sm" fixed="top">
                <Container>
                    <Navbar.Brand as={Link} to="/" className="fw-bold text-white"><i className="fa fa-map-marked-alt"></i> TRAVEL GIS</Navbar.Brand>
                    <Navbar.Toggle aria-controls="responsive-navbar-nav" />
                    <Navbar.Collapse id="responsive-navbar-nav">
                    <Nav className="me-auto">
                        <NavDropdown title={<span><i className="fa fa-list-ul"></i> CATEGORIES</span> } id="collasible-nav-dropdown" className="fw-bold text-white">
                        {
                            categories.map((category) => (
                                <NavDropdown.Item as={Link} to={`/category/${category.slug}`} key={category.id}><img src={category.image} style={{ width: "35px" }} alt=""/> {category.name.toUpperCase()}</NavDropdown.Item>
                            ))
                        }
                        <NavDropdown.Divider />
                        <NavDropdown.Item as={Link} to="/posts/direction">LIHAT LAINNYA <i className="fa fa-long-arrow-alt-right"></i></NavDropdown.Item>
                        </NavDropdown>
                        <Nav.Link as={Link} to="/places" className="fw-bold text-white"><i className="fa fa-globe-asia"></i> PLACES</Nav.Link>
                        <Nav.Link as={Link} to="/maps" className="fw-bold text-white"><i className="fa fa-map"></i> MAPS</Nav.Link>
                    </Nav>
                    <Nav>
                        <Nav.Link className="fw-bold text-white me-4"><i className="fa fa-search"></i> SEARCH</Nav.Link>
                        <Link to="/admin/login" className="btn btn-md btn-light"><i className="fa fa-lock"></i> LOGIN</Link>
                    </Nav>
                    </Navbar.Collapse>
                </Container>
            </Navbar>
        </React.Fragment>
    );
}

export default WebHeader;

Dari perubahan kode di atas, pertama kita import 2 hook dari React, yaitu useState dan useEffect.

//import react and hook
import React, { useState, useEffect } from "react";

Setelah itu, kita import konfigurasi API yang sudah pernah kita buat sebelumnya.

//import BASE URL API
import Api from "../../api";

Di dalam function component WebHeader, pertama-tama kita buat sebuah state baru yang bernama categories. State tersebut menggunakan jenis array dan digunakan untuk menampung data repsonse categories dari Rest API.

//state categories
const [categories, setCategories] = useState([]);

Kemudian kita buat sebuah function baru yang bernama fetchDataCategories. Function ini yang akan kita gunakan untuk melakukan HTTP request ke server.

//function "fetchDataCategories"
const fetchDataCategories = async () => {

	//...
	
}

Di dalam function fetchDataCategories kita melakukan fetching ke dalam endpoint /api/web/categories dengan menggunakan method GET.

//fetching Rest API "categories"
await Api.get('/api/web/categories')

Jika proses fetching berhasil dilakukan, maka kita akan assign response data-nya ke dalam state categories.

//set data to state
setCategories(response.data.data);

Agar function fetchDataCategories dapat dijalankan pertama kali saat halaman diakses, maka kita perlu memanggilnya di dalam hook useEffect.

//hook
useEffect(() => {

    //call function "fetchDataCategories"
    fetchDataCategories();

    // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

Setelah itu, untuk menampilkan data-nya di dalam JSX kita perlu melakukan perulangan menggunakan method map bawaan dari JavaScript.

<NavDropdown title={<span><i className="fa fa-list-ul"></i> CATEGORIES</span> } id="collasible-nav-dropdown" className="fw-bold text-white">
{
  categories.map((category) => (
    <NavDropdown.Item as={Link} to={`/category/${category.slug}`} key={category.id}><img src={category.image} style={{ width: "35px" }} alt=""/> {category.name.toUpperCase()}</NavDropdown.Item>
  ))
}

Sekarang jika kita reload/refresh halaman home, maka kita sudah menemukan data categories di dalam navbar menu. Kurang lebih seperti berikut ini hasilnya.

Menampilkan Data Categories di Halaman Home


Setelah berhasil menampilkan slider di halaman home, sekarang kita akan lanjutkan belajar menampilkan data categories di halaman home. Tapi kita akan buat sebuah component lagi untuk menampilkan card categories, tujuannya agar bisa digunakan berulang-ulang (reusable) di dalam component lain.

Langkah 1 - Membuat Component CardCategory

Sekarang kita akan membuat component card category terlebih dahulu. Silahkan buat file baru dengan nama CardCategory.jsx di dalam folder src/components/utilities, kemudian masukkan kode berikut ini di dalamnya.

//import react router dom
import { Link } from "react-router-dom";

function CardCategory(props) {

    return (
        <div className="col-6 col-md-3 mb-4" key={props.id}>
            <Link to={`/category/${props.slug}`} className="text-decoration-none text-dark">
                <div className="card h-100 border-0 rounded shadow-sm">
                    <div className="card-body text-center">
                        <img src={props.image} style={{ width: "80px" }} alt=""/>
                        <hr/>
                        <h6>{props.name.toUpperCase()}</h6>
                    </div>
                </div>
            </Link>
        </div>
    )
}

export default CardCategory;

Dari penambahan kode di atas, pertama kita impot provider Link dari React Router DOM. Biasanya digunakan untuk melakukan navigasi ke URL tertentu.

//import react router dom
import { Link } from "react-router-dom";

Setelah itu, di dalam function component CardCategory untuk parameter-nya terdapat sebuah props, dimana props tersebut akan berisi data yang dikirimkan oleh component lain.

function CardCategory(props) {

	//...
	
}

Dan di dalam JSX, kita tinggal menampilkan data props tersebut. Seperti id, gambar, name dan slug.

<div className="col-6 col-md-3 mb-4" key={props.id}>
    <Link to={`/category/${props.slug}`} className="text-decoration-none text-dark">
    <div className="card h-100 border-0 rounded shadow-sm">
        <div className="card-body text-center">
            <img src={props.image} style={{ width: "80px" }} alt="" />
            <hr />
            <h6>{props.name.toUpperCase()}</h6>
        </div>
    </div>
    </Link>
</div>

Langkah 2 - Menampilkan Data Categories di Home

Setelah berhasil membuat component CardCategory, sekarang kita akan lanjutkan untuk menampilkan data categories di dalam halaman home dan tentu kita akan menggunakan component tersebut disini.

Silahkan buka file src/pages/web/home/Index.jsx, kemudian ubah semua kode-nya menjadi seperti berikut ini :

//import layout
import React, { useState, useEffect } from "react";

//import layout web
import LayoutWeb from "../../../layouts/Web";

//import Slider component
import Slider from '../../../components/web/Slider';

//import BASE URL API
import Api from "../../../api";

//import cart category component
import CardCategory from "../../../components/utilities/CardCategory";

function Home() {

	//title page
    document.title = "TRAVEL GIS - Website Wisata Berbasis GIS (Geographic Information System)";

    //state categories
    const [categories, setCategories] = useState([]);

    //function "fetchDataCategories"
    const fetchDataCategories = async () => {

        //fetching Rest API
        await Api.get('/api/web/categories')
            .then((response) => {

                //set data to state
                setCategories(response.data.data)
            })
    }

    //hook
    useEffect(() => {

        //call function "fetchDataCategories"
        fetchDataCategories();

    }, []);

    return (
        <React.Fragment>
          <LayoutWeb>
      
            <Slider />

            <div className="container mb-5">
              <div className="row mt-minus-87">
                <div className="col-md-12">
                  <div className="card border-0 rounded shadow-sm">
                    <div className="card-body">
                      <h5>
                        <i className="fa fa-search"></i> FIND YOUR FAVORITE PLACE
                      </h5>
                      <p>
                        Find your favorite place to vacation with your family!
                      </p>
                      <hr />
                      <input type="text" className="form-control" placeholder="find your destination here..." />
                    </div>
                  </div>
                </div>
              </div>
              <div className="row justify-content-center mt-4">
                {
                    categories.map((category) => (
                        <CardCategory 
                          key={category.id}
                          id={category.id} 
                          name={category.name} 
                          slug={category.slug} 
                          image={category.image} 
                        />
                    ))
                }
              </div>
            </div>

          </LayoutWeb>
        </React.Fragment>
    );
}

export default Home;

Dari perubahan kode di atas, pertama kita import 2 hook dari React, yaitu useState dan useEffect.

//import layout
import React, { useState, useEffect } from "react";

Karena akan melakukan HTTP request, maka kita juga import konfigurasi API dari yang sudah kita buat sebelumnya.

//import BASE URL API
import Api from "../../../api";

Setelah itu, kita juga import component CardCategory yang sudah kita buat di atas.

//import cart category component
import CardCategory from "../../../components/utilities/CardCategory";

Di dalam function component Home, pertama-tama kita membuat sebuah state baru yang bernama categories. State tersebut akan kita gunakan untuk menyimpan response data categories yang di dapatkan dari Rest API.

//state categories
const [categories, setCategories] = useState([]);

Kemudian kita buat sebuah function baru yang bernama fetchDataCategories. Function ini yang akan kita gunakan untuk melakukan HTTP request ke server.

//function "fetchDataCategories"
const fetchDataCategories = async () => {

	//...
	
}

Di dalam function fetchDataCategories kita melakukan fetching ke dalam endpoint /api/web/categories dengan menggunakan method GET.

//fetching Rest API "categories"
await Api.get('/api/web/categories')

Jika proses fetching berhasil dilakukan, maka kita akan assign response data-nya ke dalam state categories.

//set data to state
setCategories(response.data.data);

Agar function fetchDataCategories dapat dijalankan pertama kali saat halaman diakses, maka kita perlu memanggilnya di dalam hook useEffect.

//hook
useEffect(() => {

    //call function "fetchDataCategories"
    fetchDataCategories();

    // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

Kemudian di dalam JSX kita melakukan perulangan menggunakan method map. Kurang lebih seperti berikut ini :

{
   categories.map((category) => (
   
   	//...
   
   ))
}

Di dalam perulangan kita memanggil component CardCategory dengan mengirimkan data sebagai props.

<CardCategory 
    key={category.id}
    id={category.id} 
    name={category.name} 
    slug={category.slug} 
    image={category.image} 
/>

Di atas, kita mengirimkan beberapa object seperti id, name, slug dan image sebagai data props, sehingga di dalam component CardCategory tinggal menampilkannya saja.

Sekarang jika halaman home kita reload /refresh, maka akan mengahasilkan tampilan seperti berikut ini :

Menampilkan Data Categories di Halaman Home


Setelah berhasil menampilkan slider di halaman home, sekarang kita akan lanjutkan belajar menampilkan data categories di halaman home. Tapi kita akan buat sebuah component lagi untuk menampilkan card categories, tujuannya agar bisa digunakan berulang-ulang (reusable) di dalam component lain.

Langkah 1 - Membuat Component CardCategory

Sekarang kita akan membuat component card category terlebih dahulu. Silahkan buat file baru dengan nama CardCategory.jsx di dalam folder src/components/utilities, kemudian masukkan kode berikut ini di dalamnya.

//import react router dom
import { Link } from "react-router-dom";

function CardCategory(props) {

    return (
        <div className="col-6 col-md-3 mb-4" key={props.id}>
            <Link to={`/category/${props.slug}`} className="text-decoration-none text-dark">
                <div className="card h-100 border-0 rounded shadow-sm">
                    <div className="card-body text-center">
                        <img src={props.image} style={{ width: "80px" }} alt=""/>
                        <hr/>
                        <h6>{props.name.toUpperCase()}</h6>
                    </div>
                </div>
            </Link>
        </div>
    )
}

export default CardCategory;

Dari penambahan kode di atas, pertama kita impot provider Link dari React Router DOM. Biasanya digunakan untuk melakukan navigasi ke URL tertentu.

//import react router dom
import { Link } from "react-router-dom";

Setelah itu, di dalam function component CardCategory untuk parameter-nya terdapat sebuah props, dimana props tersebut akan berisi data yang dikirimkan oleh component lain.

function CardCategory(props) {

	//...
	
}

Dan di dalam JSX, kita tinggal menampilkan data props tersebut. Seperti id, gambar, name dan slug.

<div className="col-6 col-md-3 mb-4" key={props.id}>
    <Link to={`/category/${props.slug}`} className="text-decoration-none text-dark">
    <div className="card h-100 border-0 rounded shadow-sm">
        <div className="card-body text-center">
            <img src={props.image} style={{ width: "80px" }} alt="" />
            <hr />
            <h6>{props.name.toUpperCase()}</h6>
        </div>
    </div>
    </Link>
</div>

Langkah 2 - Menampilkan Data Categories di Home

Setelah berhasil membuat component CardCategory, sekarang kita akan lanjutkan untuk menampilkan data categories di dalam halaman home dan tentu kita akan menggunakan component tersebut disini.

Silahkan buka file src/pages/web/home/Index.jsx, kemudian ubah semua kode-nya menjadi seperti berikut ini :

//import layout
import React, { useState, useEffect } from "react";

//import layout web
import LayoutWeb from "../../../layouts/Web";

//import Slider component
import Slider from '../../../components/web/Slider';

//import BASE URL API
import Api from "../../../api";

//import cart category component
import CardCategory from "../../../components/utilities/CardCategory";

function Home() {

	//title page
    document.title = "TRAVEL GIS - Website Wisata Berbasis GIS (Geographic Information System)";

    //state categories
    const [categories, setCategories] = useState([]);

    //function "fetchDataCategories"
    const fetchDataCategories = async () => {

        //fetching Rest API
        await Api.get('/api/web/categories')
            .then((response) => {

                //set data to state
                setCategories(response.data.data)
            })
    }

    //hook
    useEffect(() => {

        //call function "fetchDataCategories"
        fetchDataCategories();

    }, []);

    return (
        <React.Fragment>
          <LayoutWeb>
      
            <Slider />

            <div className="container mb-5">
              <div className="row mt-minus-87">
                <div className="col-md-12">
                  <div className="card border-0 rounded shadow-sm">
                    <div className="card-body">
                      <h5>
                        <i className="fa fa-search"></i> FIND YOUR FAVORITE PLACE
                      </h5>
                      <p>
                        Find your favorite place to vacation with your family!
                      </p>
                      <hr />
                      <input type="text" className="form-control" placeholder="find your destination here..." />
                    </div>
                  </div>
                </div>
              </div>
              <div className="row justify-content-center mt-4">
                {
                    categories.map((category) => (
                        <CardCategory 
                          key={category.id}
                          id={category.id} 
                          name={category.name} 
                          slug={category.slug} 
                          image={category.image} 
                        />
                    ))
                }
              </div>
            </div>

          </LayoutWeb>
        </React.Fragment>
    );
}

export default Home;

Dari perubahan kode di atas, pertama kita import 2 hook dari React, yaitu useState dan useEffect.

//import layout
import React, { useState, useEffect } from "react";

Karena akan melakukan HTTP request, maka kita juga import konfigurasi API dari yang sudah kita buat sebelumnya.

//import BASE URL API
import Api from "../../../api";

Setelah itu, kita juga import component CardCategory yang sudah kita buat di atas.

//import cart category component
import CardCategory from "../../../components/utilities/CardCategory";

Di dalam function component Home, pertama-tama kita membuat sebuah state baru yang bernama categories. State tersebut akan kita gunakan untuk menyimpan response data categories yang di dapatkan dari Rest API.

//state categories
const [categories, setCategories] = useState([]);

Kemudian kita buat sebuah function baru yang bernama fetchDataCategories. Function ini yang akan kita gunakan untuk melakukan HTTP request ke server.

//function "fetchDataCategories"
const fetchDataCategories = async () => {

	//...
	
}

Di dalam function fetchDataCategories kita melakukan fetching ke dalam endpoint /api/web/categories dengan menggunakan method GET.

//fetching Rest API "categories"
await Api.get('/api/web/categories')

Jika proses fetching berhasil dilakukan, maka kita akan assign response data-nya ke dalam state categories.

//set data to state
setCategories(response.data.data);

Agar function fetchDataCategories dapat dijalankan pertama kali saat halaman diakses, maka kita perlu memanggilnya di dalam hook useEffect.

//hook
useEffect(() => {

    //call function "fetchDataCategories"
    fetchDataCategories();

    // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

Kemudian di dalam JSX kita melakukan perulangan menggunakan method map. Kurang lebih seperti berikut ini :

{
   categories.map((category) => (
   
   	//...
   
   ))
}

Di dalam perulangan kita memanggil component CardCategory dengan mengirimkan data sebagai props.

<CardCategory 
    key={category.id}
    id={category.id} 
    name={category.name} 
    slug={category.slug} 
    image={category.image} 
/>

Di atas, kita mengirimkan beberapa object seperti id, name, slug dan image sebagai data props, sehingga di dalam component CardCategory tinggal menampilkannya saja.

Sekarang jika halaman home kita reload /refresh, maka akan mengahasilkan tampilan seperti berikut ini :

Beranda Mundur Maju