Как я создал приложение для электронной коммерции с помощью Medusa и Ionic


Введение

Ionic — это набор инструментов с открытым исходным кодом, который позволяет разработчикам создавать кросс-платформенные приложения, поддерживающие различные мобильные платформы, включая Android и iOS. Разработчики могут создавать приложения на основе выбранного ими фреймворка, включая Angular, Vue и React.

Medusa — это композитная платформа электронной коммерции с открытым исходным кодом, которая позволяет разработчикам создавать свои собственные настраиваемые и расширяемые интернет-магазины. Цель Medusa — предоставить разработчикам большой опыт создания уникальных магазинов электронной коммерции.

В этом уроке вы создадите приложение для электронной коммерции с помощью Medusa и Ionic. Это приложение можно будет использовать на мобильных телефонах, таких как Android, iOS и Windows phone, а также в качестве прогрессивного веб-приложения (PWA).

Вы можете просмотреть исходный код этого руководства в этом репозитории на GitHub.

Необходимые условия

Чтобы использовать Medusa, на вашей машине должен быть установлен Node.js (версия 14+). Вы можете загрузить его с официального сайта Node.js.

Настройка сервера Medusa

Сначала установите Medusa CLI, выполнив следующую команду в терминале:

npm install -g @medusajs/medusa-cli
Войти в полноэкранный режим Выйти из полноэкранного режима

Затем выполните следующую команду для создания нового сервера Medusa:

medusa new ecommerce-store-server --seed
Войти в полноэкранный режим Выйти из полноэкранного режима

Флаг --seed заполняет базу данных демонстрационными данными, которые в дальнейшем могут быть использованы как часть магазина электронной коммерции.

Наконец, перейдите в каталог ecommerce-store-server и запустите сервер:

cd ecommerce-store-server
medusa develop
Войдите в полноэкранный режим Выйти из полноэкранного режима

Если сервер запустится успешно, вы должны увидеть в терминале вывод, подобный этому:

Установите Medusa Admin

Далее настало время установить и запустить панель управления Medusa Admin. В отдельной директории выполните следующую команду:

git clone https://github.com/medusajs/admin medusa-admin
Войти в полноэкранный режим Выйти из полноэкранного режима

Перейдите во вновь созданную директорию medusa-admin и установите зависимости для проекта:

cd medusa-admin
npm install
Войти в полноэкранный режим Выйти из полноэкранного режима

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

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

Это запустит администратора Medusa на localhost:7000. Убедитесь, что сервер Medusa также запущен.

Если вы откроете Medusa Admin, вы должны увидеть страницу входа в систему.

Поскольку вы создали сервер Medusa в предыдущем разделе с флагом --seed, в дополнение к демонстрационным данным был создан тестовый пользователь. Поэтому для входа в систему вы можете использовать email admin@medusa-test.com и пароль supersecret.

Администратор Medusa включает в себя множество функций, таких как просмотр заказов, управление товарами, настройка магазина и регионов и многое другое!

Вы можете попробовать отредактировать некоторые из существующих демо-продуктов или добавить новые продукты в админке Medusa.

Инициализация проекта Ionic

В этом разделе вы приступите к созданию приложения Ionic.

Сначала установите Ionic CLI, выполнив следующую команду:

npm install -g @ionic/cli
Войти в полноэкранный режим Выйти из полноэкранного режима

Затем в отдельной директории создайте новое приложение Ionic, выполнив следующую команду:

ionic start ecommerce-store blank --type=react
Enter fullscreen mode Выйти из полноэкранного режима

В этом руководстве для создания приложения Ionic используется React. Это указывается в команде выше с помощью флага --type.

Обычно установка всех зависимостей, необходимых для проекта, занимает несколько минут.

После завершения установки перейдите в каталог ecommerce-store и установите другие необходимые зависимости:

cd ecommerce-store
npm install axios
Войдите в полноэкранный режим Выйти из полноэкранного режима

axios используется для отправки асинхронных запросов на сервер Medusa. Это позволит вам выполнять такие операции, как выборка товаров.

Тестирование приложения Ionic

Чтобы протестировать пустое приложение ionic, выполните следующую команду в терминале:

ionic serve --lab
Войти в полноэкранный режим Выйти из полноэкранного режима

Это запустит сервер Ionic для разработки на localhost:8100 и Ionic Lab на localhost:8200. Вы можете использовать Ionic Lab для симуляции того, как приложение выглядит на различных устройствах, таких как iOS или Android.

Изменение переменной CORS магазина

Поскольку приложение Ionic работает на порту 8100, вам необходимо изменить параметры Store CORS на сервере Medusa в файле medusa-config.js на следующие:

const STORE_CORS = process.env.STORE_CORS || "http://localhost:8100"
Войти в полноэкранный режим Выйти из полноэкранного режима

Для получения дополнительной информации ознакомьтесь с этим официальным руководством по обновлению настроек CORS.

После внесения этих изменений обязательно перезапустите сервер Medusa.

Создание карточек товаров

В этом разделе вы создадите компонент многоразового использования для отображения товаров в виде карточек на главной странице.

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

Для этого создайте файл src/Interfaces.tsx со следующим содержимым:

export interface Product {
    id: string;
    title: string;
    handle: string;
    images: Image[];
    description: string;
    variants: any[];
}

export interface Image {
    url: string;
}
Вход в полноэкранный режим Выход из полноэкранного режима

Далее вы создадите многоразовый компонент карточки товара.

Теперь, когда интерфейсы определены и экспортированы, пришло время создать пользовательский интерфейс для карточек товаров.

Создайте новый файл src/components/ProductItemCard/ProductItemCard.tsx со следующим содержимым:

import React, { useEffect } from 'react';
import { IonCard, IonCardHeader, IonCardSubtitle, IonImg, IonCardTitle } from '@ionic/react';
import { Product } from '../../Interfaces';

const ProductItemCard = ({ product }: { product: Product }) => {

  return (
    <div>
      {product && (
        <IonCard routerLink={"/product/" + product["id"]} className="product_card">
          <IonImg src={product.images[0]["url"]} class="image" />
          <IonCardHeader>
            <IonCardTitle className="product_title"><b>{product["title"]}</b></IonCardTitle>
            <IonCardSubtitle>{product["handle"]}</IonCardSubtitle>
            <IonCardSubtitle>${product["variants"][0]["prices"][1]["amount"] / 100}</IonCardSubtitle>
          </IonCardHeader>
        </IonCard>
      )}
    </div>

  );
};

export default ProductItemCard;
Вход в полноэкранный режим Выход из полноэкранного режима

Каждая карточка отображает изображение, название, тип и цену товара. Компоненту передается реквизит продукта, после чего отображаются соответствующие метаданные. Интерфейс Product используется для принудительного определения типа реквизита product.

Создание макета Home

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

Файлы Home.tsx и Home.css создаются по умолчанию в src/pages при инициализации проекта Ionic. Создайте новый каталог src/pages/Home и переместите Home.tsx и Home.css в каталог src/pages/Home.

Редактирование заголовка

Если вы откроете файл src/pages/Home/Home.tsx и посмотрите на возвращаемый JSX, вы увидите, что заголовок был автоматически добавлен для вас. Вы можете заменить текст, вложенный в компонент IonTitle, на название вашего магазина электронной коммерции. Например:

<IonHeader>
    <IonToolbar>
      <IonTitle>Medusa Ecommerce Store</IonTitle>
    </IonToolbar>
</IonHeader>
Вход в полноэкранный режим Выйти из полноэкранного режима

Получение товаров с сервера Medusa

Создайте файл src/server-url.js со следующим содержимым:

const medusaServerBaseURL = "http://localhost:9000";

export default medusaServerBaseURL;
Вход в полноэкранный режим Выйти из полноэкранного режима

Полезно определить базовый URL сервера Medusa в одном файле. Затем, если порт или URL нужно будет обновить, вам нужно будет обновить только URL в этом файле.

Если вы тестируете на мобильном устройстве, URL следует изменить на IP вашего компьютера.

Далее, в src/pages/Home/Home.tsx, замените импорт в начале файла на следующий:

import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar, IonGrid, IonRow, IonCol, } from '@ionic/react';
import './Home.css';
import React, { useEffect, useState } from 'react';
import axios from "axios";
import ProductItemCard from '../../components/ProductItemCard/ProductItemCard';
import medusaServerBaseURL from "../../server-url";
Вход в полноэкранный режим Выйти из полноэкранного режима

Затем создайте переменную состояния внутри компонента Home для хранения продуктов:

const [products, setProducts] = useState([]);
Войти в полноэкранный режим Выйти из полноэкранного режима

И добавьте следующее после создания переменной состояния:

useEffect(() => {
    axios
      .get(`${medusaServerBaseURL}/store/products`)
      .then((response) => {

        if (response.data) {
          let products = response.data.products;

          setProducts(products);
        }
      })
      .catch((err) => {
        console.log("error", err)
      });
  }, []);
Войти в полноэкранный режим Выйти из полноэкранного режима

С помощью useEffect компонент Home будет получать продукты с сервера при первом открытии экрана. Запрос отправляется с помощью axios на конечную точку List Products. Затем результат используется для установки переменной состояния products.

Создание сетки продуктов

Далее пришло время создать сетку товаров с помощью компонента <IonGrid>.

Все еще в src/pages/Home/Home.tsx, добавьте следующее в элемент <IonContent> в возвращаемом JSX, заменив компонент <ExploreContainer>:

<IonGrid class="ion-no-padding ion-no-margin">
    <IonRow>
     {products.map((product, i) =>
         <IonCol size="6">
             <ProductItemCard product={product} />
         </IonCol>)}
     </IonRow>
</IonGrid>
Вход в полноэкранный режим Выход из полноэкранного режима

Эта сетка отображает каждый товар с помощью компонента ProductItemCard. В каждой строке отображается два продукта, но если вы хотите изменить это на один продукт в строке, обновите параметр size для элемента IonCol на 12. Для получения дополнительной информации о сетках в Ionic, обязательно ознакомьтесь с официальной документацией.

Добавьте CSS

Измените содержимое src/pages/Home/Home.css, чтобы добавить несколько полезных стилей:

.product_card {
    cursor: pointer;
}

.product_title {
    font-size: 1em;
}
Вход в полноэкранный режим Выход из полноэкранного режима

Тестирование главного экрана

Убедитесь, что сервер Medusa все еще запущен, и повторно запустите сервер Ionic, если он еще не запущен.

Если вы откроете приложение в Ionic lab, на главном экране вы должны увидеть товары, полученные с сервера Medusa.

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

Создание экрана подробной информации о продукте

В этом разделе вы создадите экран ProductDetail. На этом экране будет отображаться информация и изображение отдельного продукта.

Создайте файл src/pages/ProductDetailPage/ProductDetailPage.tsx со следующим содержимым:

import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react';
import './ProductDetailPage.css';
import React, { useEffect, useState } from 'react';
import { IonCard, IonCardHeader, IonBackButton, IonButtons, IonCardSubtitle, IonToast, IonImg, IonCardTitle, IonCardContent, IonButton } from '@ionic/react';
import axios from "axios";
import { RouteComponentProps } from 'react-router-dom';
import { Product } from '../../Interfaces';
import medusaServerBaseURL from "../../server-url";

const ProductDetailPage: React.FC<RouteComponentProps<{ id: string }>> = (props) => {
  const [product, setProduct] = useState<Product>();

  useEffect(() => {
    let product_id = props.match.params.id;

    axios
      .get(`${medusaServerBaseURL}/store/products/${product_id}`)
      .then((response) => {
        if (response.data.product) {
          setProduct(response.data.product);
        }
      })
      .catch((err) => {
        console.log("error", err)
      });
  }, [props.match.params.id])

  return (
    <IonPage>
      <IonHeader>
        <IonToolbar>
          <IonButtons slot="start">
            <IonBackButton text="">
            </IonBackButton>
          </IonButtons>
          <IonTitle>Medusa Ecommerce Store</IonTitle>
        </IonToolbar>
      </IonHeader>
      <IonContent fullscreen>

        {product && (

          <IonCard mode="ios">
            {product["images"] && (
              <IonImg class="product_detail_img" src={product.images[0]["url"]} />
            )}
            <IonCardHeader>
              <div className="metaInfo">
                <IonCardTitle>{product["title"]}</IonCardTitle>
                <IonCardSubtitle>{product["handle"]}</IonCardSubtitle>
                <h3>${product["variants"][0]["prices"][1]["amount"] / 100}</h3>
              </div>

            </IonCardHeader>
            <IonCardContent>
              <h3>Description</h3>
              {product["description"]}
              <IonButton class="button" size="default" shape="round" expand="block">Add to Cart</IonButton>

            </IonCardContent>
          </IonCard>
        )}

      </IonContent>
    </IonPage>
  );
};

export default ProductDetailPage;
Вход в полноэкранный режим Выход из полноэкранного режима

На этой странице ID продукта извлекается из параметров маршрута. Затем библиотека axios используется для отправки запроса к конечной точке Retrieve Product на сервере Medusa для получения данных об отдельном продукте. Затем, используя ответ на запрос, устанавливается переменная состояния product.

Далее создайте файл src/pages/ProductDetailPage/ProductDetailPage.css со следующим содержимым:

.product_detail_img {
    height: 30vh;
    object-fit: cover;
}

@media (prefers-color-scheme: light) {  
    h3 {   
         color: black;  
    }
}

h3 {
    font-weight: bold;
}

.button {
    margin-top: 1em;
}

.metaInfo {
    display: flex;
    flex-direction: column;
    flex-wrap: wrap;
}
Вход в полноэкранный режим Выход из полноэкранного режима

Добавление нового маршрута

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

Сначала импортируйте компонент ProductDetailPage в src/App.tsx:

import ProductDetailPage from './pages/ProductDetailPage/ProductDetailPage';
Вход в полноэкранный режим Выйти из полноэкранного режима

Затем добавьте новый маршрут в список маршрутов, определенных в App:

const App: React.FC = () => (
  <IonApp>
    <IonReactRouter>
      <IonRouterOutlet>
        <Route exact path="/home">
          <Home />
        </Route>
        <Route exact path="/">
          <Redirect to="/home" />
        </Route>
        <Route path="/product/:id/" component={ProductDetailPage} />

      </IonRouterOutlet>
    </IonReactRouter>
  </IonApp>
);
Войти в полноэкранный режим Выйти из полноэкранного режима

Экран подробной информации о тестируемом продукте

Пока серверы разработки Medusa и Ionic все еще работают, откройте Ionic Lab в браузере и нажмите на один из продуктов на главном экране. Откроется новый экран с подробной информацией о продукте.

Показать уведомление о добавлении в корзину

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

В файле src/pages/ProductDetailPage/ProductDetailPage.tsx добавьте следующее после создания переменной состояния product, чтобы создать новую переменную состояния, управляющую видимостью уведомления о тосте:

const [showToast, setShowToast] = useState(false);
Войти в полноэкранный режим Выйти из полноэкранного режима

Затем добавьте компонент IonToast в возвращаемый JSX. Он должен быть размещен внутри IonContent и после компонента IonCard:

<IonContent fullscreen>
   {product && (

     <IonCard mode="ios">
            ...
     </IonCard>
    )}

    <IonToast
      isOpen={showToast}
      onDidDismiss={() => setShowToast(false)}
      message="Product added to cart"
      duration={800}
    />

</IonContent>
Вход в полноэкранный режим Выход из полноэкранного режима

Наконец, измените кнопку Добавить в корзину и добавьте обработчик события onClick:

<IonButton class="button" size="default" shape="round" expand="block"  
onClick={() => setShowToast(true)}>Add to Cart</IonButton>
Войти в полноэкранный режим Выход из полноэкранного режима

Теперь при нажатии на кнопку значение showToast будет установлено в true, чтобы показать уведомление о тосте.

Тестирование уведомления

Пока серверы разработки Medusa и Ionic все еще запущены, на экране подробностей одного из продуктов нажмите кнопку Добавить в корзину. В течение нескольких секунд будет отображаться уведомление о том, что продукт был добавлен в корзину.

Что дальше?

Следуя этому руководству, вы успешно подключили свое приложение Ionic к серверу Medusa и получили товары с сервера.

С помощью сервера Medusa в приложение Ionic можно добавить больше функций, в том числе:

  • Добавление функциональности корзины, позволяющей покупателям добавлять товары в корзину и управлять ее содержимым.
  • Реализация потока Checkout, позволяющего клиентам оформлять заказ.
  • Интеграция провайдера платежей, такого как Stripe

Если у вас возникнут какие-либо проблемы или вопросы, связанные с Medusa, обращайтесь к команде Medusa через Discord.

Оцените статью
devanswers.ru
Добавить комментарий