カートに入れました

商品を追加したときにhtmlタグでダイアログ表示させる。

サーバー不要Gatsbyプロジェクトで商品を売る方法。stripeの決済機能実装。

Gatsbyjsで作ったサイトにStripeの決済機能を組み込み、ショッピングカート機能をつける

上のリンクの続きになります

表示結果

add-to-cart

コード修正

dialogタグはhtml要素の上位に配置したいためgatsby-browser.jsに書き加える

gatsby-browser.js
import './src/style.css'
import 'prismjs/themes/prism.css'

import React from "react"
import { CartProvider } from 'use-shopping-cart'

export const wrapRootElement = ({ element }) => {
  return (
    <CartProvider
      mode={"payment"}
      cartMode={"client-only"}
      stripe={process.env.GATSBY_STRIPE_PUBLISHABLE_KEY}
      successUrl={'https://hi1t0.com/checkout-success'}
      cancelUrl={'https://hi1t0.com/cart'}
      currency={'jpy'}
    >
      <dialog id="add-to-cart" className={`add-to-cart`}>カートに入れました</dialog>
      {element}
    </CartProvider>
  )
}

追加するボタンが押された時に、ダイアログを表示したいのでsrc/components/products/ProductCard.jsを編集する

handleAddItem関数の中で、showModal関数実行でダイアログ表示させる

setTimeoutの中で1秒経ったらダイアログを非表示にしている

document.getElementById('add-to-cart').showModal()

...

setTimeout(() => {
      document.getElementById('add-to-cart').close()
    }, 1000)

...
src/components/products/ProductCard.js
import React, { useState } from "react"
import { useShoppingCart } from 'use-shopping-cart'

...

const ProductCard = ({ product }) => {
  const [loading, setLoading] = useState(false)
  const [priceId, setPriceId] = useState(product.prices[0]?.id)
  const { checkoutSingleItem, addItem } = useShoppingCart()

  const onChangePrice = event => {
    setPriceId(event.target.value)
  }

  const handleAddItem = event => {
    setLoading(true)
    document.getElementById('add-to-cart').showModal()
    // price_idからpriceオブジェクトをフィルターする
    const priceIndex = product.prices.findIndex(p => p.id === priceId)
    const item = product.prices[priceIndex]
    addItem({price_id: item.id, price: item.unit_amount, currency: item.currency, name: product?.name,})
    setTimeout(() => {
      document.getElementById('add-to-cart').close()
      setLoading(false)
    }, 1000)
  }

  const handleSubmit = async event => {
    ...
  }

  return (
    <div className="column is-6">
      <form onSubmit={handleSubmit} className="has-text-centered">
        <div style={cardStyles}>
          {
            product.images.length > 0 ?
            <img src={product.images[0]} alt={product.name}/>
            : ''
          }
          <fieldset style={cardMain}>
            <legend style={legendStyles}>
              <h4>{product.name}</h4>
              <p>{product.description}</p>
            </legend>
            <label style={priceStyles}>
              価格{" "}
              <select name="priceSelect" style={selectBox} onChange={onChangePrice}>
                {product.prices.map(price => (
                  <option key={price.id} value={price.id}>
                    {formatPrice(price.unit_amount, price.currency)}
                  </option>
                ))}
              </select>
            </label>
          </fieldset>
          <button
            type="button"
            onClick={(e) => handleAddItem(e)}
            disabled={loading}
            style={
              loading
                ? { ...buttonStyles, ...buttonDisabledStyles }
                : buttonStyles
            }
          >
            追加する
          </button>
          <button
            disabled={loading}
            style={
              loading
                ? { ...buttonStyles, ...buttonDisabledStyles }
                : buttonStyles
            }
          >
            今すぐ買う
          </button>
        </div>
      </form>
    </div>
  )
}

export default ProductCard

ここで問題が、、、

safariで開いてみたら表示がおかしかった

iosのバージョンは15.2.1

調べてみると

ios15.4からdialogタグに対応しているらしい!

早速アップデートして確かめる

ちゃんとdialogタグが表示されるようになっています

めでたしめでたし