В современном мире большинство покупок совершается онлайн, а не лично, что делает веб-сайты электронной коммерции все более важными. Скорость веб-сайта важна, потому что некоторые могут иметь тысячи огромных изображений, которые замедляют работу веб-сайта; вот почему Cloudinary используется для хранения и сжатия всех изображений на сайте. Xata — это независимая база данных, которую можно использовать для хранения всех данных изображений.


Предпосылки для этого проекта

  • Знание Javascript, React, CSS.

  • Node.js установлен

  • Облачный аккаунт. Создай здесь если у вас нет учетной записи

Вы можете найти репозиторий для этого проекта в Гитхаб. Сделайте форк для начала. Живую демонстрацию этого проекта можно найти на Версель


Настройка изображений нашего проекта в Cloudinary

После того, как наша учетная запись Cloudinary успешно создана, мы переходим в медиатеку, где создаем папки для хранения наших изображений, а затем загружаем различные изображения для использования в нашем проекте. Cloudinary предлагает широкий спектр инструментов и эффектов, применимых к нашим изображениям, чтобы уменьшить их размер и сделать наш сайт легче.


Настройка проекта

Во-первых, мы запускаем следующую строку кода в терминале, чтобы создать новое приложение для реагирования:

npx create-react-app ecommerce-website
Войти в полноэкранный режим

Выйти из полноэкранного режима

Чтобы хранить все компоненты нашего приложения, мы создаем папку компонентов:

Затем мы запускаем следующее, чтобы установить зависимости для проекта:

​​// install React Router 
npm i react-router-dom@5.3.3

​​// install uuid 
$ npm install uuidv4

​​// install cloudinary 
npm install cloudinary-react
Войти в полноэкранный режим

Выйти из полноэкранного режима

в Home компонент, React и usestate хук импортируется, затем он экспортируется для отображения в app.js файл.
После этого мы импортируем и используем React Router для отображения компонентов приложения на основе URL-адреса страницы. Затем мы используем useState крючки для сохранения как товаров в корзине, так и текущей категории.


import React,{useState} from "react";
import {BrowserRouter as Router,Route} from "react-router-dom"


function Home (){
    const [cartItems,setCartItems]=useState([])
    const [categ,setCateg]=useState()


  return ()

}

export default Home
Войти в полноэкранный режим

Выйти из полноэкранного режима

После этого мы будем использовать useState построить массив объектов, которые будут служить нашими продуктами. Каждому продукту присваивается id который получается с помощью UUID. Мы импортируем его в приложение с помощью import {v4 as uuid} from 'uuid'

    const [products,setProducts]=useState([
        {
            title:'Blender',
            price:'15',
            categ:'electronics',
            id:uuid()
        },
        {
            title:'Apple airpods',
            price:'200',
            categ:'electronics',
            id:uuid()
        },
        {
            title:'T-shirt',
            price:'20',
            categ:'clothing',
            id:uuid()
        },
        {
            title:'Shorts',
            price:'10',
            categ:'clothing',
            id:uuid()
        },
        {
            title:'Book-1',
            price:'10',
            categ:'books',
            id:uuid()
        },
        {
            title:'Book-2',
            price:'10',
            categ:'books',
            id:uuid()
        },
        {
            title:'Barbell',
            price:'5',
            categ:'fitness',
            id:uuid()
        },
        {
            title:'Dumbbell',
            price:'10',
            categ:'fitness',
            id:uuid()
        },
        {
            title:'Phone-1',
            price:'300',
            categ:'phones',
            id:uuid()
        },
        {
            title:'Phone-2',
            price:'500',
            categ:'phones',
            id:uuid()
        },
        {
            title:'Toy truck',
            price:'17',
            categ:'toys',
            id:uuid()
        },
        {
            title:'Fidget spinner',
            price:'20',
            categ:'toys',
            id:uuid()
        }


    ])
Войти в полноэкранный режим

Выйти из полноэкранного режима


Создание функций приложения

Следующим шагом является создание функций для выполнения различных задач приложения. Для этого добавим в home составная часть:

    const addToCart=(id)=>{
        setCartItems((prevState)=>[...prevState,
            products.find((item)=>item.id===id)
        ]);
    }


    const removeFromCart =(id)=>{
        setTimeout(()=>{setCartItems(cartItems.filter((item)=> item.id !== id))},0)
    }
Войти в полноэкранный режим

Выйти из полноэкранного режима

В приведенном выше коде мы:

  • Определил addToCart функция, которая принимает id аргумент и добавляет в корзину любой товар, id свойство соответствует id аргумент.

  • Определенный RemoveFromCart функция, которая принимает id аргумент и удаляет любой продукт, чей id свойство соответствует id аргумент из корзины.


Создание наших компонентов

После этого мы создаем отдельные компоненты, которые импортируются в Home компонент позже. Они есть:

  • Категория

  • Список продуктов

  • Страница продукта

  • Корзина

  • Корзинакнопка

Первый компонент – это Category компонент, который содержит массив категорий и хранит множество групп, которые будут использоваться в этом проекте. Для каждой категории мы используем метод карты Javascript для создания div с изображением и именем. Проходит changecateg props, который доставляет выбранную категорию в домашний компонент, позволяя отображать правильный список продуктов.

import React,{useState, useEffect} from "react";
import {AdvancedImage} from '@cloudinary/react';
import {Cloudinary} from "@cloudinary/url-gen";
import {Link} from "react-router-dom"


function Category({changeCateg}){
   // define categories of products in the app 
    const categories=['electronics','clothing','books','fitness','phones','toys']

   // access cloudinary account 
  const cld = new Cloudinary({
    cloud: {
      cloudName: 'dhdmchgsh'
    }
  });
    return(
        <div className="categories">
            <h1>Shop by Category</h1>

            {categories.map((category)=>{

               // fetch image from cloudinary based on category 

                var myImage=cld.image(`categories/${category}`);

                    return (
                    <div className="category">
                        <Link to='/products' onClick={()=>changeCateg(category)} className="category-link">
                          <AdvancedImage cldImg={myImage} className="image"/>
                          <p>{category}</p>
                        </Link>                        
                      </div>

                    )})}
        </div>
    )
}

export default Category
Войти в полноэкранный режим

Выйти из полноэкранного режима

cld переменная помогает нам получить доступ к нашей облачной учетной записи, Advancedimage компонент содержит myImage prop, который передает строку в cld чтобы получить изображение для каждой категории.
Реактивный маршрутизатор Link импортируется, а затем используется для изменения URL-адреса приложения на /productsэто заставляет маршрутизатор отображать Productlist составная часть.

import React from "react";
import {AdvancedImage} from '@cloudinary/react';
import {Cloudinary} from "@cloudinary/url-gen";
import {Link} from "react-router-dom"



function Productlist ({list,category}){
    const cld = new Cloudinary({
        cloud: {
          cloudName: 'dhdmchgsh'
        }
      });

      const filteredProducts=list.filter((product)=>product.categ==category)
    return(
      <div>
      {filteredProducts.map((item)=>{
      var myImage=cld.image(`products/${item.title}`);
        return(
          <div className="product">
            <Link to={`/products/${item.title}`}  className="product-link">
              <AdvancedImage cldImg={myImage} className="image"/>
              <p>{item.title}</p>
              <span>${item.price}</span>
            </Link>
          </div>
        )
      })}
      </div>

    )
}

export default Productlist
Войти в полноэкранный режим

Выйти из полноэкранного режима

Productlist — это компонент, отображающий все продукты, доступные для выбранной категории. Пройдено и то, и другое list а также category реквизит.
list вставляет массив продуктов в Productlist компонент в то время как category выбрана категория. filteredProducts проверяет list массив и возвращает продукты, чьи categ свойство соответствует выбранной категории.
Когда на продукт нажимают, мы используем React Router useParams чтобы изменить URL-адрес страницы в соответствии с продуктом.

import React from "react";
import {AdvancedImage} from '@cloudinary/react';
import {Cloudinary} from "@cloudinary/url-gen";
import {useParams} from "react-router-dom";


function Productpage({addToCart,list}){
    const cld = new Cloudinary({
        cloud: {
          cloudName: 'dhdmchgsh'
        }
      });
      const {title}=useParams()

    return(
      <div>
            {list.filter((item)=>item.title === title).map((item)=>{
              var myImage=cld.image(`products/${item.title}`)
              return(
              <div className="product-page">
                <AdvancedImage cldImg={myImage} className="big-image"/>
                <div>
                  <h5>{item.title}</h5>
                  <p>${item.price}</p>
                  <button className="firstbtn" onClick={()=>{addToCart(item.id)}}>ADD TO CART</button>
                  <button>BUY NOW</button>
                </div>
              </div>
              )})}
      </div>
    )
}

export default Productpage
Войти в полноэкранный режим

Выйти из полноэкранного режима

Вслед за этим следует Productpage компонент, который показывает информацию о продукте. Ему предоставляется реквизит «список», который представляет собой массив продуктов, и addToCart это функция, которая вызывается при нажатии первой кнопки.
Мы импортируем useParams затем назначается titleэто изменяет URL-адрес приложения на основе title свойство продукта, по которому щелкнули. Нажмите здесь узнать больше о useParams.

import React from "react";
import {AdvancedImage} from '@cloudinary/react';
import {Cloudinary} from "@cloudinary/url-gen";

function Cart({cartItems,removeItem}){
    const cld = new Cloudinary({
        cloud: {
          cloudName: 'dhdmchgsh'
        }
      });
    return(
        <div >
            {cartItems.map((item)=>{
                var myImage=cld.image(`products/${item.title}`)
                return (
                <div className="cart">
                    <AdvancedImage cldImg={myImage} className="cart-image"/>
                    <div>
                        <h6>{item.title}</h6>
                        <p>${item.price}</p>
                        <button onClick={()=>{removeItem(item.id)}}>DELETE</button>
                    </div>
                </div>
                )})}
        </div>
    )
}

export default Cart
Войти в полноэкранный режим

Выйти из полноэкранного режима

Теперь, когда мы определили Productpage компонент, следующим шагом будет создание Cart компонент, который будет отображать все продукты, которые в настоящее время хранятся в cartItems переменная. Проходит removeItem prop, который удаляет продукт, используя его id имущество.

import React from 'react'
import {Link} from 'react-router-dom'
import cart from '../images/cart.jpg'

function Cartbutton(){
    return(
        <div className="cart-button">
            <Link to='/cart' className="cart-button-link">
                    <img src={cart}/>
                    <span>Cart</span>
            </Link>
        </div>
    )
}


export default Cartbutton
Войти в полноэкранный режим

Выйти из полноэкранного режима

Мы успешно определили наш Cart компонент, но нам по-прежнему нужен способ доступа к нему, поэтому мы создаем Cartbutton который отображает React Router Link компонент, который изменяет URL-адрес приложения на /cart который отображает корзину.


Импорт наших компонентов в Home.js

Все компоненты, которые будут использоваться в этом приложении, определены, но их необходимо импортировать в Home компонент для отображения.

import Productlist from "./Productlist";
import Cart from "./Cart";
import Category from "./Category";
import Productpage from "./Productpage";
import Cartbutton from "./Cartbutton";
Войти в полноэкранный режим

Выйти из полноэкранного режима

После этого заменяем return заявление в Home компонент со следующим:

    return(
        <div className="home">
            <div className="header">
                <div className="logo">easy<span>Buy</span></div>
            </div>
            <Router>
                <Route path="
                <Route exact path=" changeCateg={categ=>setCateg(categ)}/></Route> 
                <Route exact path="/products"><Productlist  list={products} category={categ} /></Route>
                <Route exact path="/products/:title"><Productpage list={products} addToCart={addToCart}/></Route>
                <Route exact path="/cart"><Cart cartItems={cartItems} removeItem={removeFromCart}/></Route>
            </Router>
        </div>
    )
Войти в полноэкранный режим

Выйти из полноэкранного режима

Route содержащий Cartbutton задан путь «, чтобы он отображался на каждой странице приложения. exact гарантирует, что соответствующий компонент отображается только тогда, когда URL-адрес страницы совпадает с path.
Далее мы стилизуем наше приложение в app.css.

Описание изображения


Вывод

В этой статье показано, как создать простой веб-сайт электронной коммерции, используя хуки Cloudinary и React для хранения изображений и значений соответственно. Xata также можно использовать для хранения продуктов в защищенной базе данных.