Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

migrated to pnpm, next-js example, fixed warning #310

Merged
merged 18 commits into from Mar 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
136 changes: 67 additions & 69 deletions .github/workflows/test-pull-requests.yml
Expand Up @@ -6,7 +6,7 @@ name: Tests

on:
pull_request:
branches: [ master, next, dev ]
branches: [master, next, dev]

jobs:
test-package:
Expand All @@ -16,86 +16,84 @@ jobs:
- macos-latest
strategy:
matrix:
node_version: [ '12', '14', '16' ]
node_version: ['12', '14', '16']
steps:
- uses: actions/checkout@v2
# Set up Node and Yarn
- uses: actions/[email protected]
with:
# Version Spec of the version to use. Examples: 12.x, 10.15.1, >=10.15.0
node-version: ${{ matrix.node-version }}
# Used to specify a package manager for caching in the default directory. Supported values: npm, yarn
cache: yarn
- uses: actions/checkout@v2
# Set up Node and Yarn
- uses: actions/[email protected]
with:
# Version Spec of the version to use. Examples: 12.x, 10.15.1, >=10.15.0
node-version: ${{ matrix.node-version }}
# Used to specify a package manager for caching in the default directory. Supported values: npm, yarn
cache: yarn

# Caching for Yarn
- id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
# Caching for Yarn
- id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-

# Install dependencies
- run: yarn workspace use-shopping-cart install --frozen-lockfile
# Run integration and unit tests
- run: yarn workspace use-shopping-cart test
# Run TypeScript type definition tests
- run: yarn workspace use-shopping-cart test:types
# Install dependencies
- run: pnpm install --frozen-lockfile
# Run integration and unit tests
- run: pnpm --filter use-shopping-cart run test
# Run TypeScript type definition tests
- run: pnpm --filter use-shopping-cart run test:types

build-package:
name: Build
runs-on:
ubuntu-latest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16
cache: yarn
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16
cache: yarn

# Caching for Yarn
- id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-

# Caching for Yarn
- id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
# Install dependencies
- run: pnpm install
# Build package
- run: pnpm --filter use-shopping-cart run build

# Install dependencies
- run: yarn workspace use-shopping-cart install --frozen-lockfile
# Build package
- run: yarn workspace use-shopping-cart build

lint-package:
continue-on-error: true
name: Lint
runs-on:
ubuntu-latest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16
cache: yarn
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16
cache: yarn

# Caching for Yarn
- id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
# Caching for Yarn
- id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-

# Install dependencies
- run: yarn workspace use-shopping-cart install --frozen-lockfile
# Lint soure code
- run: yarn workspace use-shopping-cart lint
# Install dependencies
- run: pnpm install --frozen-lockfile
# Lint soure code
- run: pnpm --filter use-shopping-cart run lint
Empty file added .husky/pre-commit
Empty file.
1 change: 1 addition & 0 deletions .npmrc
@@ -0,0 +1 @@
auto-install-peers=true
6 changes: 4 additions & 2 deletions docs/package.json
Expand Up @@ -11,10 +11,11 @@
"serve": "docusaurus serve"
},
"dependencies": {
"@docusaurus/core": "2.0.0-alpha.70",
"@docusaurus/preset-classic": "2.0.0-alpha.70",
"@docusaurus/core": "2.3.1",
"@docusaurus/preset-classic": "2.3.1",
"@mdx-js/react": "^1.6.22",
"clsx": "^1.1.1",
"prism-react-renderer": "^1.3.5",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"use-shopping-cart": "3.1.0"
Expand All @@ -32,3 +33,4 @@
]
}
}

6 changes: 6 additions & 0 deletions docs/src/components/landing-page/codeExamples.js
@@ -1,3 +1,9 @@
const process = {
env: {
URL: 'https://useshoppingcart.com'
}
}

export const exampleProducts = `
[
{
Expand Down
2 changes: 1 addition & 1 deletion docs/src/theme/Root.js
Expand Up @@ -9,7 +9,7 @@ function Root({ children }) {
<CartProvider
mode="payment"
cartMode="checkout-session"
stripe={process.env.REACT_APP_STRIPE_API_PUBLIC}
stripe={''}
billingAddressCollection={false}
successUrl="https://stripe.com"
cancelUrl="https://twitter.com/dayhaysoos"
Expand Down
2 changes: 1 addition & 1 deletion examples/cra/package.json
Expand Up @@ -10,7 +10,7 @@
"react-dom": "^17.0.2",
"react-scripts": "^4.0.3",
"theme-ui": "^0.10.0",
"use-shopping-cart": "file:../../use-shopping-cart",
"use-shopping-cart": "workspace:^3.1.4",
"web-vitals": "^1.0.1"
},
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion examples/gatsby/package.json
Expand Up @@ -19,7 +19,7 @@
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-helmet": "^5.2.1",
"use-shopping-cart": "*"
"use-shopping-cart": "workspace:^3.1.4"
},
"keywords": [
"gatsby"
Expand Down
32 changes: 32 additions & 0 deletions examples/nextjs/.gitignore
@@ -0,0 +1,32 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
.env*.local

# vercel
.vercel
2 changes: 2 additions & 0 deletions examples/nextjs/README.md
@@ -0,0 +1,2 @@
Resources used:
- [Tabler icons](https://tabler-icons.io/) for shopping cart icon
30 changes: 30 additions & 0 deletions examples/nextjs/components/CartItem.js
@@ -0,0 +1,30 @@
import { useShoppingCart } from "use-shopping-cart";
import { formatCurrencyString } from "use-shopping-cart";
import Image from "next/image";

export default function CartItem({ item }) {
const { name, emoji, quantity, price } = item;
const { removeItem } = useShoppingCart();

const removeItemFromCart = () => {
removeItem(item.id);
};

return (
<div className="flex items-center gap-4 mb-3">
<p className="text-4xl">{emoji}</p>
<div>
{name} <span className="text-xs">({quantity})</span>
</div>
<div className="ml-auto">
{formatCurrencyString({ value: price, currency: "GBP" })}
</div>
<button
onClick={() => removeItemFromCart()}
className="hover:bg-emerald-50 transition-colors rounded-full duration-500 p-1"
>
<Image alt="delete icon" src="./trash.svg" width={20} height={20} />
</button>
</div>
);
}
55 changes: 55 additions & 0 deletions examples/nextjs/components/CheckoutButton.js
@@ -0,0 +1,55 @@
import { useState } from "react";
import { useShoppingCart } from "use-shopping-cart";

export default function CheckoutButton() {
const [status, setStatus] = useState("idle");
const { redirectToCheckout, cartCount, totalPrice } = useShoppingCart();

async function handleClick(event) {
event.preventDefault();
if (cartCount > 0) {
setStatus("loading");
try {
const result = await redirectToCheckout();
if (result?.error) {
console.error(result);
setStatus("redirect-error");
}
} catch (error) {
console.error(error);
setStatus("redirect-error");
}
} else {
setStatus("no-items");
}
}

return (
<article className="mt-3 flex flex-col">
<div className="text-red-700 text-xs mb-3 h-5 text-center">
{totalPrice && totalPrice < 30
? "You must have at least £0.30 in your basket"
: cartCount && cartCount > 20
? "You cannot have more than 20 items"
: status === "redirect-error"
? "Unable to redirect to Stripe checkout page"
: status === "no-items"
? "Please add some items to your cart"
: null}
</div>
<button
onClick={handleClick}
className="bg-emerald-50 hover:bg-emerald-500 hover:text-white transition-colors duration-500 text-emerald-500 py-3 px-5 rounded-md w-100 disabled:bg-slate-300 disabled:cursor-not-allowed disabled:text-white"
disabled={
(totalPrice && totalPrice < 30) ||
(cartCount && cartCount > 20) ||
status == "no-items"
? true
: false
}
>
{status !== "loading" ? "Proceed to checkout" : "Loading..."}
</button>
</article>
);
}
22 changes: 22 additions & 0 deletions examples/nextjs/components/Layout.js
@@ -0,0 +1,22 @@
import Head from "next/head";
import NavBar from "./NavBar";

export default function Layout({ children }) {
return (
<>
<Head>
<title>fresh</title>
<meta
name="description"
content="A simple website to show how to use use-shopping-cart"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
</Head>
<NavBar />
<main className="bg-[#f8f7f5] min-h-[calc(100vh-76px)] px-10 py-8">
<div className="container md:mx-auto md:max-w-[850px]">{children}</div>
</main>
</>
);
}
29 changes: 29 additions & 0 deletions examples/nextjs/components/NavBar.js
@@ -0,0 +1,29 @@
import { useShoppingCart } from "use-shopping-cart";
import Image from "next/image";
import Link from "next/link";
import ShoppingCart from "./ShoppingCart";

export default function NavBar() {
const { handleCartClick, cartCount } = useShoppingCart();
return (
<nav className="py-5 px-12 flex justify-between">
<Link href="/">
<p className="bg-white text-3xl font-bold underline underline-offset-4 decoration-wavy decoration-2 decoration-emerald-500">
fresh
</p>
</Link>
<button className="relative" onClick={() => handleCartClick()}>
<Image
src="./cart.svg"
width={40}
height={40}
alt="shopping cart icon"
/>
<div className="rounded-full flex justify-center items-center bg-emerald-500 text-xs text-white absolute w-6 h-5 bottom-6 -right-1">
{cartCount}
</div>
</button>
<ShoppingCart />
</nav>
);
}