From 875f46196bf90c79ad0ae4b3d026e870e9eae9eb Mon Sep 17 00:00:00 2001 From: "shopify[bot]" <79544226+shopify[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 07:57:56 +0000 Subject: [PATCH] Create a new Hydrogen project --- .eslintignore | 5 + .eslintrc.cjs | 12 + .../oxygen-deployment-1000020231.yml | 44 + .gitignore | 9 + .graphqlrc.yml | 12 + .npmrc | 2 + CHANGELOG.md | 574 + README.md | 46 +- app/assets/favicon.svg | 28 + app/components/Aside.jsx | 77 + app/components/Cart.jsx | 369 + app/components/Footer.jsx | 130 + app/components/Header.jsx | 240 + app/components/PageLayout.jsx | 132 + app/components/Search.jsx | 515 + app/entry.client.jsx | 12 + app/entry.server.jsx | 56 + .../CustomerAddressMutations.js | 61 + .../customer-account/CustomerDetailsQuery.js | 40 + .../customer-account/CustomerOrderQuery.js | 87 + .../customer-account/CustomerOrdersQuery.js | 58 + .../CustomerUpdateMutation.js | 24 + app/lib/fragments.js | 174 + app/lib/search.js | 27 + app/lib/session.js | 75 + app/lib/variants.js | 51 + app/root.jsx | 213 + app/routes/$.jsx | 15 + app/routes/[robots.txt].jsx | 123 + app/routes/[sitemap.xml].jsx | 187 + app/routes/_index.jsx | 195 + app/routes/account.$.jsx | 18 + app/routes/account._index.jsx | 7 + app/routes/account.addresses.jsx | 571 + app/routes/account.jsx | 90 + app/routes/account.orders.$id.jsx | 216 + app/routes/account.orders._index.jsx | 129 + app/routes/account.profile.jsx | 166 + app/routes/account_.authorize.jsx | 9 + app/routes/account_.login.jsx | 9 + app/routes/account_.logout.jsx | 18 + app/routes/api.predictive-search.jsx | 309 + .../blogs.$blogHandle.$articleHandle.jsx | 126 + app/routes/blogs.$blogHandle._index.jsx | 197 + app/routes/blogs._index.jsx | 132 + app/routes/cart.$lines.jsx | 73 + app/routes/cart.jsx | 113 + app/routes/collections.$handle.jsx | 237 + app/routes/collections._index.jsx | 158 + app/routes/collections.all.jsx | 201 + app/routes/discount.$code.jsx | 51 + app/routes/pages.$handle.jsx | 97 + app/routes/policies.$handle.jsx | 105 + app/routes/policies._index.jsx | 70 + app/routes/products.$handle.jsx | 483 + app/routes/search.jsx | 186 + app/styles/app.css | 486 + app/styles/reset.css | 129 + customer-accountapi.generated.d.ts | 509 + env.d.ts | 54 + jsconfig.json | 19 + package-lock.json | 22455 ++++++++++++++++ package.json | 50 + public/.gitkeep | 0 server.js | 117 + storefrontapi.generated.d.ts | 1211 + vite.config.js | 41 + 67 files changed, 32434 insertions(+), 1 deletion(-) create mode 100644 .eslintignore create mode 100644 .eslintrc.cjs create mode 100644 .github/workflows/oxygen-deployment-1000020231.yml create mode 100644 .gitignore create mode 100644 .graphqlrc.yml create mode 100644 .npmrc create mode 100644 CHANGELOG.md create mode 100644 app/assets/favicon.svg create mode 100644 app/components/Aside.jsx create mode 100644 app/components/Cart.jsx create mode 100644 app/components/Footer.jsx create mode 100644 app/components/Header.jsx create mode 100644 app/components/PageLayout.jsx create mode 100644 app/components/Search.jsx create mode 100644 app/entry.client.jsx create mode 100644 app/entry.server.jsx create mode 100644 app/graphql/customer-account/CustomerAddressMutations.js create mode 100644 app/graphql/customer-account/CustomerDetailsQuery.js create mode 100644 app/graphql/customer-account/CustomerOrderQuery.js create mode 100644 app/graphql/customer-account/CustomerOrdersQuery.js create mode 100644 app/graphql/customer-account/CustomerUpdateMutation.js create mode 100644 app/lib/fragments.js create mode 100644 app/lib/search.js create mode 100644 app/lib/session.js create mode 100644 app/lib/variants.js create mode 100644 app/root.jsx create mode 100644 app/routes/$.jsx create mode 100644 app/routes/[robots.txt].jsx create mode 100644 app/routes/[sitemap.xml].jsx create mode 100644 app/routes/_index.jsx create mode 100644 app/routes/account.$.jsx create mode 100644 app/routes/account._index.jsx create mode 100644 app/routes/account.addresses.jsx create mode 100644 app/routes/account.jsx create mode 100644 app/routes/account.orders.$id.jsx create mode 100644 app/routes/account.orders._index.jsx create mode 100644 app/routes/account.profile.jsx create mode 100644 app/routes/account_.authorize.jsx create mode 100644 app/routes/account_.login.jsx create mode 100644 app/routes/account_.logout.jsx create mode 100644 app/routes/api.predictive-search.jsx create mode 100644 app/routes/blogs.$blogHandle.$articleHandle.jsx create mode 100644 app/routes/blogs.$blogHandle._index.jsx create mode 100644 app/routes/blogs._index.jsx create mode 100644 app/routes/cart.$lines.jsx create mode 100644 app/routes/cart.jsx create mode 100644 app/routes/collections.$handle.jsx create mode 100644 app/routes/collections._index.jsx create mode 100644 app/routes/collections.all.jsx create mode 100644 app/routes/discount.$code.jsx create mode 100644 app/routes/pages.$handle.jsx create mode 100644 app/routes/policies.$handle.jsx create mode 100644 app/routes/policies._index.jsx create mode 100644 app/routes/products.$handle.jsx create mode 100644 app/routes/search.jsx create mode 100644 app/styles/app.css create mode 100644 app/styles/reset.css create mode 100644 customer-accountapi.generated.d.ts create mode 100644 env.d.ts create mode 100644 jsconfig.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/.gitkeep create mode 100644 server.js create mode 100644 storefrontapi.generated.d.ts create mode 100644 vite.config.js diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..a362bca --- /dev/null +++ b/.eslintignore @@ -0,0 +1,5 @@ +build +node_modules +bin +*.d.ts +dist diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..9f070de --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,12 @@ +/** + * @type {import("@types/eslint").Linter.BaseConfig} + */ +module.exports = { + extends: ['@remix-run/eslint-config', 'plugin:hydrogen/recommended'], + rules: { + 'hydrogen/prefer-image-component': 'off', + 'no-useless-escape': 'off', + 'no-case-declarations': 'off', + 'no-console': ['warn', {allow: ['warn', 'error']}], + }, +}; diff --git a/.github/workflows/oxygen-deployment-1000020231.yml b/.github/workflows/oxygen-deployment-1000020231.yml new file mode 100644 index 0000000..15a1a9d --- /dev/null +++ b/.github/workflows/oxygen-deployment-1000020231.yml @@ -0,0 +1,44 @@ +# Don't change the line below! +#! oxygen_storefront_id: 1000020231 + +name: Storefront 1000020231 +on: [push] + +permissions: + contents: read + deployments: write + +jobs: + deploy: + name: Deploy to Oxygen + timeout-minutes: 30 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup node.js + uses: actions/setup-node@v4 + with: + node-version: "lts/*" + check-latest: true + + - name: Cache node modules + id: cache-npm + uses: actions/cache@v4 + env: + cache-name: cache-node-modules + with: + path: ~/.npm + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + + - name: Install dependencies + run: npm ci + + - name: Build and Publish to Oxygen + run: npx shopify hydrogen deploy + env: + SHOPIFY_HYDROGEN_DEPLOYMENT_TOKEN: ${{ secrets.OXYGEN_DEPLOYMENT_TOKEN_1000020231 }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..400e97f --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +node_modules +/.DS_Store +/.cache +/build +/dist +/public/build +/.mf +.env +.shopify diff --git a/.graphqlrc.yml b/.graphqlrc.yml new file mode 100644 index 0000000..eee81ed --- /dev/null +++ b/.graphqlrc.yml @@ -0,0 +1,12 @@ +projects: + default: + schema: 'node_modules/@shopify/hydrogen/storefront.schema.json' + documents: + - '!*.d.ts' + - '*.{ts,tsx,js,jsx}' + - 'app/**/*.{ts,tsx,js,jsx}' + - '!app/graphql/**/*.{ts,tsx,js,jsx}' + customer-account: + schema: 'node_modules/@shopify/hydrogen/customer-account.schema.json' + documents: + - 'app/graphql/customer-account/**/*.{ts,tsx,js,jsx}' diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..2050a65 --- /dev/null +++ b/.npmrc @@ -0,0 +1,2 @@ +@shopify:registry=https://registry.npmjs.com +progress=false diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3c9e70f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,574 @@ +# skeleton + +## 2024.4.9 + +### Patch Changes + +- Updated dependencies [[`9957968b`](https://github.com/Shopify/hydrogen/commit/9957968b664cf4314952c84e90f993d5118ebf73)]: + - @shopify/hydrogen@2024.4.7 + +## 2024.4.8 + +### Patch Changes + +- Updated dependencies [[`593dd30e`](https://github.com/Shopify/hydrogen/commit/593dd30e87bd64f9b8b9b42bfc631482039a480a)]: + - @shopify/hydrogen@2024.4.6 + +## 2024.4.7 + +### Patch Changes + +- Fix paths on Windows. ([#2243](https://github.com/Shopify/hydrogen/pull/2243)) by [@michenly](https://github.com/michenly) + +- Updated dependencies [[`31452380`](https://github.com/Shopify/hydrogen/commit/31452380340e079cd4ec1f8c10cdab5e5313e921)]: + - @shopify/hydrogen@2024.4.5 + - @shopify/cli-hydrogen@8.1.1 + +## 2024.4.6 + +### Patch Changes + +- Updated dependencies [[`707afb96`](https://github.com/Shopify/hydrogen/commit/707afb96fd1ef64a59a14182f60ca61718b372d1)]: + - @shopify/hydrogen@2024.4.4 + +## 2024.4.5 + +### Patch Changes + +- Update remix to v2.9.2 ([#2135](https://github.com/Shopify/hydrogen/pull/2135)) by [@michenly](https://github.com/michenly) + +- `` and `useAnalytics` are now stable. ([#2141](https://github.com/Shopify/hydrogen/pull/2141)) by [@wizardlyhel](https://github.com/wizardlyhel) + +- Update the skeleton template to use React state in the aside dialogs ([#2088](https://github.com/Shopify/hydrogen/pull/2088)) by [@blittle](https://github.com/blittle) + +- Updated dependencies [[`fe82119f`](https://github.com/Shopify/hydrogen/commit/fe82119f5e75df5a0f727bab6a2186e679abc73d), [`32d4c33e`](https://github.com/Shopify/hydrogen/commit/32d4c33e4421a9c56f62a8c392f5417edddd0402), [`8eea75ec`](https://github.com/Shopify/hydrogen/commit/8eea75ec5ead4de98d7d1b2baedce8511029bcae), [`27e51abf`](https://github.com/Shopify/hydrogen/commit/27e51abfc1f5444afa952c503886bfa12fc55c7e), [`f29c9085`](https://github.com/Shopify/hydrogen/commit/f29c9085eb1adbde9e01226484eba8a85b5074ed), [`7b838beb`](https://github.com/Shopify/hydrogen/commit/7b838beb7c43380ffc9c32c2bb9f34291912fa42), [`d702aec2`](https://github.com/Shopify/hydrogen/commit/d702aec2214646a78cdafc2c25d510489db73f6d), [`ca4cf045`](https://github.com/Shopify/hydrogen/commit/ca4cf045f7fb72ad98b62af7bd172ff8cf553de2), [`5a554b2e`](https://github.com/Shopify/hydrogen/commit/5a554b2e9d91894c2db8032f0c29666dce1ea3f2), [`27e51abf`](https://github.com/Shopify/hydrogen/commit/27e51abfc1f5444afa952c503886bfa12fc55c7e), [`5d6465b3`](https://github.com/Shopify/hydrogen/commit/5d6465b32d90052e5580fcb81d98427bcb8ad528), [`608389d6`](https://github.com/Shopify/hydrogen/commit/608389d6d69c6a9801935d528507c165d1dd4ccf), [`9dfd1cfe`](https://github.com/Shopify/hydrogen/commit/9dfd1cfeb3e96c6d3426427a4b5d97ef475dab6d), [`7def3e9f`](https://github.com/Shopify/hydrogen/commit/7def3e9fa6e28f4fde7af43e2f346aa32267c38e), [`65239c76`](https://github.com/Shopify/hydrogen/commit/65239c76ca1d0b294b59b1ad53624485859c4da5), [`ca7f2888`](https://github.com/Shopify/hydrogen/commit/ca7f28887367a4882e57a67c4e248b0f0bba1c9b)]: + - @shopify/hydrogen@2024.4.3 + - @shopify/cli-hydrogen@8.1.0 + +## 2024.4.4 + +### Patch Changes + +- Add JSdoc to `getSelectedProductOptions` utility and cleanup the skeleton implementation ([#2089](https://github.com/Shopify/hydrogen/pull/2089)) by [@juanpprieto](https://github.com/juanpprieto) + +- Updated dependencies [[`286589ee`](https://github.com/Shopify/hydrogen/commit/286589ee281c161ad323e3d45a8b9b859aa5b11f), [`6f5061d9`](https://github.com/Shopify/hydrogen/commit/6f5061d9432f749fde7902548894e98c0d3f899c), [`ae262b61`](https://github.com/Shopify/hydrogen/commit/ae262b616127a7173d23a1a38a6e658af3105ce8), [`2c11ca3b`](https://github.com/Shopify/hydrogen/commit/2c11ca3b7a00ccca2b621dbc29abd319f9598cc8), [`b70f9c2c`](https://github.com/Shopify/hydrogen/commit/b70f9c2c3db8e863c65509097454b9ad7c81cd52), [`17528db1`](https://github.com/Shopify/hydrogen/commit/17528db1eb3d1baa001bafe0684b4bce28d2e271), [`58ea9bb0`](https://github.com/Shopify/hydrogen/commit/58ea9bb0f0eee83ff89e34e2f1f6ac3c4999e213)]: + - @shopify/cli-hydrogen@8.0.4 + - @shopify/hydrogen@2024.4.2 + +## 1.0.10 + +### Patch Changes + +- Update `@shopify/cli` dependency to avoid React version mismatches in your project: ([#2059](https://github.com/Shopify/hydrogen/pull/2059)) by [@frandiox](https://github.com/frandiox) + + ```diff + "dependencies": { + ... + - "@shopify/cli": "3.58.0", + + "@shopify/cli": "3.59.2", + ... + } + ``` + +- Updated dependencies [[`d2bc720b`](https://github.com/Shopify/hydrogen/commit/d2bc720bb5f7cfb5f42617f98ad2dfcd29891f4b)]: + - @shopify/cli-hydrogen@8.0.3 + +## 1.0.9 + +### Patch Changes + +- Pin React dependency to 18.2.0 to avoid mismatches. ([#2051](https://github.com/Shopify/hydrogen/pull/2051)) by [@frandiox](https://github.com/frandiox) + +- Updated dependencies [[`9c36c8a5`](https://github.com/Shopify/hydrogen/commit/9c36c8a566b1ae2ceac4846c4c9fe4f63f6f4ab3)]: + - @shopify/cli-hydrogen@8.0.2 + +## 1.0.8 + +### Patch Changes + +- Stop inlining the favicon in base64 to avoid issues with the Content-Security-Policy. In `vite.config.js`: ([#2006](https://github.com/Shopify/hydrogen/pull/2006)) by [@frandiox](https://github.com/frandiox) + + ```diff + export default defineConfig({ + plugins: [ + ... + ], + + build: { + + assetsInlineLimit: 0, + + }, + }); + ``` + +- To improve HMR in Vite, move the `useRootLoaderData` function from `app/root.tsx` to a separate file like `app/lib/root-data.ts`. This change avoids circular imports: ([#2014](https://github.com/Shopify/hydrogen/pull/2014)) by [@frandiox](https://github.com/frandiox) + + ```tsx + // app/lib/root-data.ts + import {useMatches} from '@remix-run/react'; + import type {SerializeFrom} from '@shopify/remix-oxygen'; + import type {loader} from '~/root'; + + /** + * Access the result of the root loader from a React component. + */ + export const useRootLoaderData = () => { + const [root] = useMatches(); + return root?.data as SerializeFrom; + }; + ``` + + Import this hook from `~/lib/root-data` instead of `~/root` in your components. + +- Updated dependencies [[`b4dfda32`](https://github.com/Shopify/hydrogen/commit/b4dfda320ca52855b2d4493a4306d15a883ca843), [`ffa57bdb`](https://github.com/Shopify/hydrogen/commit/ffa57bdbcdf51e03d565736f9388b5bb4f46292c), [`ac4e1670`](https://github.com/Shopify/hydrogen/commit/ac4e1670f0361a2cd2c6827e4162bbbee0ca37f3), [`0af624d5`](https://github.com/Shopify/hydrogen/commit/0af624d51afc7250db889ba5e736c85a6070c8b2), [`9723eaf3`](https://github.com/Shopify/hydrogen/commit/9723eaf3e5a42c30e657d1cadb123ed775d620e4), [`e842f68c`](https://github.com/Shopify/hydrogen/commit/e842f68c8e879d4c54e0730f3cb55214a760d7f5)]: + - @shopify/cli-hydrogen@8.0.1 + - @shopify/hydrogen@2024.4.1 + +## 1.0.7 + +### Patch Changes + +- Update internal libraries for parsing `.env` files. ([#1946](https://github.com/Shopify/hydrogen/pull/1946)) by [@aswamy](https://github.com/aswamy) + + Please update the `@shopify/cli` dependency in your app to avoid duplicated subdependencies: + + ```diff + "dependencies": { + - "@shopify/cli": "3.56.3", + + "@shopify/cli": "3.58.0", + } + ``` + +- Add Adds magic Catalog route ([#1967](https://github.com/Shopify/hydrogen/pull/1967)) by [@juanpprieto](https://github.com/juanpprieto) + +- Update Vite plugin imports, and how their options are passed to Remix: ([#1935](https://github.com/Shopify/hydrogen/pull/1935)) by [@frandiox](https://github.com/frandiox) + + ```diff + -import {hydrogen, oxygen} from '@shopify/cli-hydrogen/experimental-vite'; + +import {hydrogen} from '@shopify/hydrogen/vite'; + +import {oxygen} from '@shopify/mini-oxygen/vite'; + import {vitePlugin as remix} from '@remix-run/dev'; + + export default defineConfig({ + hydrogen(), + oxygen(), + remix({ + - buildDirectory: 'dist', + + presets: [hydrogen.preset()], + future: { + ``` + +- Add `@shopify/mini-oxygen` as a dev dependency for local development: ([#1891](https://github.com/Shopify/hydrogen/pull/1891)) by [@frandiox](https://github.com/frandiox) + + ```diff + "devDependencies": { + "@remix-run/dev": "^2.8.0", + "@remix-run/eslint-config": "^2.8.0", + + "@shopify/mini-oxygen": "^3.0.0", + "@shopify/oxygen-workers-types": "^4.0.0", + ... + }, + ``` + +- Add the `customer-account push` command to the Hydrogen CLI. This allows you to push the current `--dev-origin` URL to the Shopify admin to enable secure connection to the Customer Account API for local development. ([#1804](https://github.com/Shopify/hydrogen/pull/1804)) by [@michenly](https://github.com/michenly) + +- Fix types returned by the `session` object. ([#1869](https://github.com/Shopify/hydrogen/pull/1869)) by [@frandiox](https://github.com/frandiox) + + In `remix.env.d.ts` or `env.d.ts`, add the following types: + + ```diff + import type { + // ... + HydrogenCart, + + HydrogenSessionData, + } from '@shopify/hydrogen'; + + // ... + + declare module '@shopify/remix-oxygen' { + // ... + + + interface SessionData extends HydrogenSessionData {} + } + ``` + +- Codegen dependencies must be now listed explicitly in `package.json`: ([#1962](https://github.com/Shopify/hydrogen/pull/1962)) by [@frandiox](https://github.com/frandiox) + + ```diff + { + "devDependencies": { + + "@graphql-codegen/cli": "5.0.2", + "@remix-run/dev": "^2.8.0", + "@remix-run/eslint-config": "^2.8.0", + + "@shopify/hydrogen-codegen": "^0.3.0", + "@shopify/mini-oxygen": "^2.2.5", + "@shopify/oxygen-workers-types": "^4.0.0", + ... + } + } + ``` + +- Updated dependencies [[`4eaec272`](https://github.com/Shopify/hydrogen/commit/4eaec272696f1a718aa7cab1070a54385ebc3686), [`14bb5df1`](https://github.com/Shopify/hydrogen/commit/14bb5df1c1513a7991183d34e72220cb2b139cf5), [`646b78d4`](https://github.com/Shopify/hydrogen/commit/646b78d4bc26310121b16000ed4d1c5d5e63957d), [`87072950`](https://github.com/Shopify/hydrogen/commit/870729505f7eb1f1c709799dd036ad02fd94be95), [`5f1295fe`](https://github.com/Shopify/hydrogen/commit/5f1295fe60b86396f364fefef339248a444c988a), [`3c8a7313`](https://github.com/Shopify/hydrogen/commit/3c8a7313cafb0ca21bbca19ac0b3f8ef4ab12655), [`ca1dcbb7`](https://github.com/Shopify/hydrogen/commit/ca1dcbb7d69c458006e25892c86c4478d394a428), [`11879b17`](https://github.com/Shopify/hydrogen/commit/11879b175d78e3326de090a56a044d1e55d0bae8), [`f4d6e5b0`](https://github.com/Shopify/hydrogen/commit/f4d6e5b0244392a7c13b9fa51c5046fd103c3e4f), [`788d86b3`](https://github.com/Shopify/hydrogen/commit/788d86b3a737bff53b4ec3aa9667458b2d45ade7), [`ebaf5529`](https://github.com/Shopify/hydrogen/commit/ebaf5529287b24a70b3146444b18f95b64f9f336), [`da95bb1c`](https://github.com/Shopify/hydrogen/commit/da95bb1c8c644f450053ce649b40dc380e7375dc), [`5bb43304`](https://github.com/Shopify/hydrogen/commit/5bb43304c08427786cfd4f2529e59bd38f593252), [`140e4768`](https://github.com/Shopify/hydrogen/commit/140e4768c880aaed4ba95b1d4c707df6963e011c), [`062d6be7`](https://github.com/Shopify/hydrogen/commit/062d6be7e031c388498ec3d359de51a4bfdfdfd8), [`b3323e59`](https://github.com/Shopify/hydrogen/commit/b3323e59a4381647f1df797c5dc54793f6e0a29a), [`ab0df5a5`](https://github.com/Shopify/hydrogen/commit/ab0df5a52bc587515880ae26f4edd18ba2be83cd), [`ebaf5529`](https://github.com/Shopify/hydrogen/commit/ebaf5529287b24a70b3146444b18f95b64f9f336), [`ebaf5529`](https://github.com/Shopify/hydrogen/commit/ebaf5529287b24a70b3146444b18f95b64f9f336), [`9e899218`](https://github.com/Shopify/hydrogen/commit/9e8992181ce7d27548d35f98b5a4f78b80795ce8), [`a209019f`](https://github.com/Shopify/hydrogen/commit/a209019f722ece4b65f8d5f37c8018c949956b1e), [`d007b7bc`](https://github.com/Shopify/hydrogen/commit/d007b7bc6f6c36e984d937108230ecc7c202fa42), [`a5511cd7`](https://github.com/Shopify/hydrogen/commit/a5511cd7bf9b0f0c4ef0e52cd72418f78c04785b), [`4afedb4d`](https://github.com/Shopify/hydrogen/commit/4afedb4d7202715df9a153e877e8eb281cc3e928), [`34fbae23`](https://github.com/Shopify/hydrogen/commit/34fbae23999eefbd1af1dff44816a52813d75b44), [`e3baaba5`](https://github.com/Shopify/hydrogen/commit/e3baaba54c701a48923ab3fe8078278f2db2c53f), [`99d72f7a`](https://github.com/Shopify/hydrogen/commit/99d72f7afc354abb66ed0e4ffb020bede2781286), [`9351f9f5`](https://github.com/Shopify/hydrogen/commit/9351f9f564267124bcbf986f5550a542c4bf1e30)]: + - @shopify/cli-hydrogen@8.0.0 + - @shopify/hydrogen@2024.4.0 + - @shopify/remix-oxygen@2.0.4 + +## 1.0.6 + +### Patch Changes + +- Improve performance of predictive search: ([#1823](https://github.com/Shopify/hydrogen/pull/1823)) by [@frandiox](https://github.com/frandiox) + + - Change the request to be GET instead of POST to avoid Remix route revalidations. + - Add Cache-Control headers to the response to get quicker results when typing. + + Aside from that, it now shows a loading state when fetching the results instead of "No results found.". + +- Updated dependencies [[`351b3c1b`](https://github.com/Shopify/hydrogen/commit/351b3c1b7768870793ff072ba91426107ba0180c), [`5060cf57`](https://github.com/Shopify/hydrogen/commit/5060cf57f69d8391b425b54acaa487af1f7405ae), [`2888014e`](https://github.com/Shopify/hydrogen/commit/2888014e54fab72c150e9eca55df3c6dd789503e)]: + - @shopify/hydrogen@2024.1.4 + - @shopify/cli-hydrogen@7.1.2 + +## 1.0.5 + +### Patch Changes + +- Update the `@shopify/cli` dependency: ([#1786](https://github.com/Shopify/hydrogen/pull/1786)) by [@frandiox](https://github.com/frandiox) + + ```diff + - "@shopify/cli": "3.52.0", + + "@shopify/cli": "3.56.3", + ``` + +- Update Remix and associated packages to 2.8.0. ([#1781](https://github.com/Shopify/hydrogen/pull/1781)) by [@frandiox](https://github.com/frandiox) + + ```diff + "dependencies": { + - "@remix-run/react": "^2.6.0", + - "@remix-run/server-runtime": "^2.6.0", + + "@remix-run/react": "^2.8.0", + + "@remix-run/server-runtime": "^2.8.0", + //... + }, + "devDependencies": { + - "@remix-run/dev": "^2.6.0", + - "@remix-run/eslint-config": "^2.6.0", + + "@remix-run/dev": "^2.8.0", + + "@remix-run/eslint-config": "^2.8.0", + //... + }, + ``` + +- Updated dependencies [[`ced1d4cb`](https://github.com/Shopify/hydrogen/commit/ced1d4cb5b1eeeb4303449eb1d60aac44f33480e), [`fc013401`](https://github.com/Shopify/hydrogen/commit/fc013401c5727948b602c9c6b6963a2df21cbd38), [`e641255e`](https://github.com/Shopify/hydrogen/commit/e641255eccc5783b41c8fabbc88313a610f539d0), [`d7e04cb6`](https://github.com/Shopify/hydrogen/commit/d7e04cb6a33d40ea86fa8ac2712d7a5ea785de2d), [`eedd9c49`](https://github.com/Shopify/hydrogen/commit/eedd9c497b36aba47a641cecbc710e18f5b14e46)]: + - @shopify/cli-hydrogen@7.1.1 + - @shopify/hydrogen@2024.1.3 + +## 1.0.4 + +### Patch Changes + +- This is an important fix to a bug with 404 routes and path-based i18n projects where some unknown routes would not properly render a 404. This fixes all new projects, but to fix existing projects, add a `($locale).tsx` route with the following contents: ([#1732](https://github.com/Shopify/hydrogen/pull/1732)) by [@blittle](https://github.com/blittle) + + ```ts + import {type LoaderFunctionArgs} from '@remix-run/server-runtime'; + + export async function loader({params, context}: LoaderFunctionArgs) { + const {language, country} = context.storefront.i18n; + + if ( + params.locale && + params.locale.toLowerCase() !== `${language}-${country}`.toLowerCase() + ) { + // If the locale URL param is defined, yet we still are still at the default locale + // then the the locale param must be invalid, send to the 404 page + throw new Response(null, {status: 404}); + } + + return null; + } + ``` + +- Add defensive null checks to the default cart implementation in the starter template ([#1746](https://github.com/Shopify/hydrogen/pull/1746)) by [@blittle](https://github.com/blittle) + +- 🐛 Fix issue where customer login does not persist to checkout ([#1719](https://github.com/Shopify/hydrogen/pull/1719)) by [@michenly](https://github.com/michenly) + + ✨ Add `customerAccount` option to `createCartHandler`. Where a `?logged_in=true` will be added to the checkoutUrl for cart query if a customer is logged in. + +- Updated dependencies [[`faeba9f8`](https://github.com/Shopify/hydrogen/commit/faeba9f8947d6b9420b33274a0f39b62418ff2e5), [`6d585026`](https://github.com/Shopify/hydrogen/commit/6d585026623204e99d54a5f2efa3d1c74f690bb6), [`fcecfb23`](https://github.com/Shopify/hydrogen/commit/fcecfb2307210b9d73a7cc90ba865508937217ba), [`28864d6f`](https://github.com/Shopify/hydrogen/commit/28864d6ffbb19b62a5fb8f4c9bbe27568de62411), [`c0ec7714`](https://github.com/Shopify/hydrogen/commit/c0ec77141fb1d7a713d91219b8777bc541780ae8), [`226cf478`](https://github.com/Shopify/hydrogen/commit/226cf478a5bdef1cca33fe8f69832ae0e557d9d9), [`06d9fd91`](https://github.com/Shopify/hydrogen/commit/06d9fd91140bd52a8ee41a20bc114ce2e7fb67dc)]: + - @shopify/cli-hydrogen@7.1.0 + - @shopify/hydrogen@2024.1.2 + +## 1.0.3 + +### Patch Changes + +- ♻️ `CustomerClient` type is deprecated and replaced by `CustomerAccount` ([#1692](https://github.com/Shopify/hydrogen/pull/1692)) by [@michenly](https://github.com/michenly) + +- Updated dependencies [[`02798786`](https://github.com/Shopify/hydrogen/commit/02798786bf8ae5c53f6430723a86d62b8e94d120), [`52b15df4`](https://github.com/Shopify/hydrogen/commit/52b15df457ce723bbc83ad594ded73a7b06447d6), [`a2664362`](https://github.com/Shopify/hydrogen/commit/a2664362a7d89b34835553a9b0eb7af55ca70ae4), [`eee5d927`](https://github.com/Shopify/hydrogen/commit/eee5d9274b72404dfb0ffef30d5503fd553be5fe), [`c7b2017f`](https://github.com/Shopify/hydrogen/commit/c7b2017f11a2cb4d280dfd8f170e65a908b9ea02), [`06320ee4`](https://github.com/Shopify/hydrogen/commit/06320ee48b94dbfece945461031a252f454fd0a3)]: + - @shopify/hydrogen@2024.1.1 + - @shopify/cli-hydrogen@7.0.1 + +## 1.0.2 + +### Patch Changes + +- Use new parameters introduced in Storefront API v2024-01 to fix redirection to the product's default variant when there are unknown query params in the URL. ([#1642](https://github.com/Shopify/hydrogen/pull/1642)) by [@wizardlyhel](https://github.com/wizardlyhel) + + ```diff + - selectedVariant: variantBySelectedOptions(selectedOptions: $selectedOptions) { + + selectedVariant: variantBySelectedOptions(selectedOptions: $selectedOptions, ignoreUnknownOptions: true, caseInsensitiveMatch: true) { + ...ProductVariant + } + ``` + +- Update the GraphQL config in `.graphqlrc.yml` to use the more modern `projects` structure: ([#1577](https://github.com/Shopify/hydrogen/pull/1577)) by [@frandiox](https://github.com/frandiox) + + ```diff + -schema: node_modules/@shopify/hydrogen/storefront.schema.json + +projects: + + default: + + schema: 'node_modules/@shopify/hydrogen/storefront.schema.json' + ``` + + This allows you to add additional projects to the GraphQL config, such as third party CMS schemas. + + Also, you can modify the document paths used for the Storefront API queries. This is useful if you have a large codebase and want to exclude certain files from being used for codegen or other GraphQL utilities: + + ```yaml + projects: + default: + schema: 'node_modules/@shopify/hydrogen/storefront.schema.json' + documents: + - '!*.d.ts' + - '*.{ts,tsx,js,jsx}' + - 'app/**/*.{ts,tsx,js,jsx}' + ``` + +- Improve resiliency of `HydrogenSession` ([#1583](https://github.com/Shopify/hydrogen/pull/1583)) by [@blittle](https://github.com/blittle) + +- Update `@shopify/cli` dependency in `package.json`: ([#1579](https://github.com/Shopify/hydrogen/pull/1579)) by [@frandiox](https://github.com/frandiox) + + ```diff + - "@shopify/cli": "3.51.0", + + "@shopify/cli": "3.52.0", + ``` + +- - Update example and template Remix versions to `^2.5.1` ([#1639](https://github.com/Shopify/hydrogen/pull/1639)) by [@wizardlyhel](https://github.com/wizardlyhel) + + - Enable Remix future flags: + - [`v3_fetcherPersist`](https://remix.run/docs/en/main/hooks/use-fetchers#additional-resources) + - [`v3_relativeSplatpath`](https://remix.run/docs/en/main/hooks/use-resolved-path#splat-paths) + +- Updated dependencies [[`810f48cf`](https://github.com/Shopify/hydrogen/commit/810f48cf5d55f0cfcac6e01fe481db8c76e77cd2), [`8c477cb5`](https://github.com/Shopify/hydrogen/commit/8c477cb565c3e018bf4e13bad01804c21611fb8a), [`42ac4138`](https://github.com/Shopify/hydrogen/commit/42ac4138553c7e1a438b075c4f9cb781edffebc4), [`0241b7d2`](https://github.com/Shopify/hydrogen/commit/0241b7d2dcb887d259ce9033aca356d391bc07df), [`6a897586`](https://github.com/Shopify/hydrogen/commit/6a897586bd0908db90736921d11e4b6bdf29c912), [`0ff63bed`](https://github.com/Shopify/hydrogen/commit/0ff63bed840f5b8a5eb9968b67bd9a5a57099253), [`6bc1d61c`](https://github.com/Shopify/hydrogen/commit/6bc1d61c17a9c9be13f52338d2ab940e64e73495), [`eb0f4bcc`](https://github.com/Shopify/hydrogen/commit/eb0f4bccb57966a00ecb2b88d17dd694599da340), [`400bfee6`](https://github.com/Shopify/hydrogen/commit/400bfee6836a51c6ab5e4804e8b1e9ad48856dcb), [`a69c21ca`](https://github.com/Shopify/hydrogen/commit/a69c21caa15dfedb88afd50f262f17bf86f74836), [`970073e7`](https://github.com/Shopify/hydrogen/commit/970073e78258880505e0de563136b5379d5d24af), [`772118ca`](https://github.com/Shopify/hydrogen/commit/772118ca6aefbd47841fffc6ce42856c2dc779bd), [`335375a6`](https://github.com/Shopify/hydrogen/commit/335375a6b1a512f70e169a82bc87a8392dc8c92c), [`335371ce`](https://github.com/Shopify/hydrogen/commit/335371ceb6e1bd5aebb6104f131d3f22798a245f), [`94509b75`](https://github.com/Shopify/hydrogen/commit/94509b750afefd686971198ed86277e2c70f3176), [`36d6fa2c`](https://github.com/Shopify/hydrogen/commit/36d6fa2c4fa54ff79f06ef17aa41f60478977bc0), [`3e7b6e8a`](https://github.com/Shopify/hydrogen/commit/3e7b6e8a3bf66bad7fc0f9c224f1c163dbe3e288), [`cce65795`](https://github.com/Shopify/hydrogen/commit/cce6579580f849bec9a28cf575f7130ba3627f6b), [`9e3d88d4`](https://github.com/Shopify/hydrogen/commit/9e3d88d498efaa20fe23de9837e0f444180bc787), [`ca1161b2`](https://github.com/Shopify/hydrogen/commit/ca1161b29ad7b4d0838953782fb114d5fe82193a), [`92840e51`](https://github.com/Shopify/hydrogen/commit/92840e51820e5c7822f731affd3f591c0099be10), [`952fedf2`](https://github.com/Shopify/hydrogen/commit/952fedf27b869164550954d1c15f53b32ec02675), [`1bc053c9`](https://github.com/Shopify/hydrogen/commit/1bc053c94ba1be14ddc28be9eb70be7219b295d1)]: + - @shopify/hydrogen@2024.1.0 + - @shopify/cli-hydrogen@7.0.0 + - @shopify/remix-oxygen@2.0.3 + +## 1.0.1 + +### Patch Changes + +- Sync up environment variable names across all example & type files. ([#1542](https://github.com/Shopify/hydrogen/pull/1542)) by [@michenly](https://github.com/michenly) + +- Remove error boundary from robots.txt file in the Skeleton template ([#1492](https://github.com/Shopify/hydrogen/pull/1492)) by [@andrewcohen](https://github.com/andrewcohen) + +- Use the worker runtime by default when running the `dev` or `preview` commands. ([#1525](https://github.com/Shopify/hydrogen/pull/1525)) by [@frandiox](https://github.com/frandiox) + + Enable it in your project by adding the `--worker` flag to your package.json scripts: + + ```diff + "scripts": { + "build": "shopify hydrogen build", + - "dev": "shopify hydrogen dev --codegen", + + "dev": "shopify hydrogen dev --worker --codegen", + - "preview": "npm run build && shopify hydrogen preview", + + "preview": "npm run build && shopify hydrogen preview --worker", + ... + } + ``` + +- Update to the latest version of `@shopify/oxygen-workers-types`. ([#1494](https://github.com/Shopify/hydrogen/pull/1494)) by [@frandiox](https://github.com/frandiox) + + In TypeScript projects, when updating to the latest `@shopify/remix-oxygen` adapter release, you should also update to the latest version of `@shopify/oxygen-workers-types`: + + ```diff + "devDependencies": { + "@remix-run/dev": "2.1.0", + "@remix-run/eslint-config": "2.1.0", + - "@shopify/oxygen-workers-types": "^3.17.3", + + "@shopify/oxygen-workers-types": "^4.0.0", + "@shopify/prettier-config": "^1.1.2", + ... + }, + ``` + +- Update internal dependencies for bug resolution. ([#1496](https://github.com/Shopify/hydrogen/pull/1496)) by [@vincentezw](https://github.com/vincentezw) + + Update your `@shopify/cli` dependency to avoid duplicated sub-dependencies: + + ```diff + "dependencies": { + - "@shopify/cli": "3.50.2", + + "@shopify/cli": "3.51.0", + } + ``` + +- Update all Node.js dependencies to version 18. (Not a breaking change, since Node.js 18 is already required by Remix v2.) ([#1543](https://github.com/Shopify/hydrogen/pull/1543)) by [@michenly](https://github.com/michenly) + +- 🐛 fix undefined menu error ([#1533](https://github.com/Shopify/hydrogen/pull/1533)) by [@michenly](https://github.com/michenly) + +- Add `@remix-run/server-runtime` dependency. ([#1489](https://github.com/Shopify/hydrogen/pull/1489)) by [@frandiox](https://github.com/frandiox) + + Since Remix is now a peer dependency of `@shopify/remix-oxygen`, you need to add `@remix-run/server-runtime` to your dependencies, with the same version as the rest of your Remix dependencies. + + ```diff + "dependencies": { + "@remix-run/react": "2.1.0" + + "@remix-run/server-runtime": "2.1.0" + ... + } + ``` + +- Updated dependencies [[`b2a350a7`](https://github.com/Shopify/hydrogen/commit/b2a350a754ea2d29bc267c260dc298a02f8f4470), [`9b4f4534`](https://github.com/Shopify/hydrogen/commit/9b4f453407338874bd8f1a1f619b607670e021d0), [`74ea1dba`](https://github.com/Shopify/hydrogen/commit/74ea1dba9af37a146882df7ed9674be5659862b5), [`2be9ce82`](https://github.com/Shopify/hydrogen/commit/2be9ce82fd4a5121f1772bbb7349e96ed530e84e), [`a9b8bcde`](https://github.com/Shopify/hydrogen/commit/a9b8bcde96c22cedef7d87631d429199810b4a7a), [`bca112ed`](https://github.com/Shopify/hydrogen/commit/bca112ed7db49e533fe49898b663fa0dd318e6ba), [`848c6260`](https://github.com/Shopify/hydrogen/commit/848c6260a2db3a9cb0c86351f0f7128f61e028f0), [`d53b4ed7`](https://github.com/Shopify/hydrogen/commit/d53b4ed752eb0530622a666ea7dcf4b40239cafa), [`961fd8c6`](https://github.com/Shopify/hydrogen/commit/961fd8c630727784f77b9f693d2e8ff8601969fc), [`2bff9fc7`](https://github.com/Shopify/hydrogen/commit/2bff9fc75916fa95f9a9279d069408fb7a33755c), [`c8e8f6fd`](https://github.com/Shopify/hydrogen/commit/c8e8f6fd233e52cf5570b1904af710d6b907aae5), [`8fce70de`](https://github.com/Shopify/hydrogen/commit/8fce70de32bd61ee86a6d895ac43cc1f78f1bf49), [`f90e4d47`](https://github.com/Shopify/hydrogen/commit/f90e4d4713c6c1fc1e921a7ecd08e95fe5da1744), [`e8cc49fe`](https://github.com/Shopify/hydrogen/commit/e8cc49feff18f5ee72d5f6965ff2094addc23466)]: + - @shopify/cli-hydrogen@6.1.0 + - @shopify/remix-oxygen@2.0.2 + - @shopify/hydrogen@2023.10.3 + +## 1.0.0 + +### Major Changes + +- The Storefront API 2023-10 now returns menu item URLs that include the `primaryDomainUrl`, instead of defaulting to the Shopify store ID URL (example.myshopify.com). The skeleton template requires changes to check for the `primaryDomainUrl`: by [@blittle](https://github.com/blittle) + + 1. Update the `HeaderMenu` component to accept a `primaryDomainUrl` and include + it in the internal url check + + ```diff + // app/components/Header.tsx + + + import type {HeaderQuery} from 'storefrontapi.generated'; + + export function HeaderMenu({ + menu, + + primaryDomainUrl, + viewport, + }: { + menu: HeaderProps['header']['menu']; + + primaryDomainUrl: HeaderQuery['shop']['primaryDomain']['url']; + viewport: Viewport; + }) { + + // ...code + + // if the url is internal, we strip the domain + const url = + item.url.includes('myshopify.com') || + item.url.includes(publicStoreDomain) || + + item.url.includes(primaryDomainUrl) + ? new URL(item.url).pathname + : item.url; + + // ...code + + } + ``` + + 2. Update the `FooterMenu` component to accept a `primaryDomainUrl` prop and include + it in the internal url check + + ```diff + // app/components/Footer.tsx + + - import type {FooterQuery} from 'storefrontapi.generated'; + + import type {FooterQuery, HeaderQuery} from 'storefrontapi.generated'; + + function FooterMenu({ + menu, + + primaryDomainUrl, + }: { + menu: FooterQuery['menu']; + + primaryDomainUrl: HeaderQuery['shop']['primaryDomain']['url']; + }) { + // code... + + // if the url is internal, we strip the domain + const url = + item.url.includes('myshopify.com') || + item.url.includes(publicStoreDomain) || + + item.url.includes(primaryDomainUrl) + ? new URL(item.url).pathname + : item.url; + + // ...code + + ); + } + ``` + + 3. Update the `Footer` component to accept a `shop` prop + + ```diff + export function Footer({ + menu, + + shop, + }: FooterQuery & {shop: HeaderQuery['shop']}) { + return ( +
+ - + + +
+ ); + } + ``` + + 4. Update `Layout.tsx` to pass the `shop` prop + + ```diff + export function Layout({ + cart, + children = null, + footer, + header, + isLoggedIn, + }: LayoutProps) { + return ( + <> + + + +
+
{children}
+ + + - {(footer) =>
} + + {(footer) =>
} + + + + ); + } + ``` + +### Patch Changes + +- If you are calling `useMatches()` in different places of your app to access the data returned by the root loader, you may want to update it to the following pattern to enhance types: ([#1289](https://github.com/Shopify/hydrogen/pull/1289)) by [@frandiox](https://github.com/frandiox) + + ```ts + // root.tsx + + import {useMatches} from '@remix-run/react'; + import {type SerializeFrom} from '@shopify/remix-oxygen'; + + export const useRootLoaderData = () => { + const [root] = useMatches(); + return root?.data as SerializeFrom; + }; + + export function loader(context) { + // ... + } + ``` + + This way, you can import `useRootLoaderData()` anywhere in your app and get the correct type for the data returned by the root loader. + +- Updated dependencies [[`81400439`](https://github.com/Shopify/hydrogen/commit/814004397c1d17ef0a53a425ed28a42cf67765cf), [`a6f397b6`](https://github.com/Shopify/hydrogen/commit/a6f397b64dc6a0d856cb7961731ee1f86bf80292), [`3464ec04`](https://github.com/Shopify/hydrogen/commit/3464ec04a084e1ceb30ee19874dc1b9171ce2b34), [`7fc088e2`](https://github.com/Shopify/hydrogen/commit/7fc088e21bea47840788cb7c60f873ce1f253128), [`867e0b03`](https://github.com/Shopify/hydrogen/commit/867e0b033fc9eb04b7250baea97d8fd49d26ccca), [`ad45656c`](https://github.com/Shopify/hydrogen/commit/ad45656c5f663cc1a60eab5daab4da1dfd0e6cc3), [`f24e3424`](https://github.com/Shopify/hydrogen/commit/f24e3424c8e2b363b181b71fcbd3e45f696fdd3f), [`66a48573`](https://github.com/Shopify/hydrogen/commit/66a4857387148b6a104df5783314c74aca8aada0), [`0ae7cbe2`](https://github.com/Shopify/hydrogen/commit/0ae7cbe280d8351126e11dc13f35d7277d9b2d86), [`8198c1be`](https://github.com/Shopify/hydrogen/commit/8198c1befdfafb39fbcc88d71f91d21eae252973), [`ad45656c`](https://github.com/Shopify/hydrogen/commit/ad45656c5f663cc1a60eab5daab4da1dfd0e6cc3)]: + - @shopify/hydrogen@2023.10.0 + - @shopify/remix-oxygen@2.0.0 + - @shopify/cli-hydrogen@6.0.0 diff --git a/README.md b/README.md index f84e548..c584e53 100644 --- a/README.md +++ b/README.md @@ -1 +1,45 @@ -# packdigital_saurabh \ No newline at end of file +# Hydrogen template: Skeleton + +Hydrogen is Shopify’s stack for headless commerce. Hydrogen is designed to dovetail with [Remix](https://remix.run/), Shopify’s full stack web framework. This template contains a **minimal setup** of components, queries and tooling to get started with Hydrogen. + +[Check out Hydrogen docs](https://shopify.dev/custom-storefronts/hydrogen) +[Get familiar with Remix](https://remix.run/docs/en/v1) + +## What's included + +- Remix +- Hydrogen +- Oxygen +- Vite +- Shopify CLI +- ESLint +- Prettier +- GraphQL generator +- TypeScript and JavaScript flavors +- Minimal setup of components and routes + +## Getting started + +**Requirements:** + +- Node.js version 18.0.0 or higher + +```bash +npm create @shopify/hydrogen@latest +``` + +## Building for production + +```bash +npm run build +``` + +## Local development + +```bash +npm run dev +``` + +## Setup for using Customer Account API (`/account` section) + +Follow step 1 and 2 of diff --git a/app/assets/favicon.svg b/app/assets/favicon.svg new file mode 100644 index 0000000..f6c6497 --- /dev/null +++ b/app/assets/favicon.svg @@ -0,0 +1,28 @@ + + + + + diff --git a/app/components/Aside.jsx b/app/components/Aside.jsx new file mode 100644 index 0000000..3b02232 --- /dev/null +++ b/app/components/Aside.jsx @@ -0,0 +1,77 @@ +import {createContext, useContext, useState} from 'react'; + +/** + * A side bar component with Overlay + * @example + * ```jsx + * + * ``` + * @param {{ + * children?: React.ReactNode; + * type: AsideType; + * heading: React.ReactNode; + * }} + */ +export function Aside({children, heading, type}) { + const {type: activeType, close} = useAside(); + const expanded = type === activeType; + + return ( +
+ +
+
{children}
+ + + ); +} + +const AsideContext = createContext(null); + +Aside.Provider = function AsideProvider({children}) { + const [type, setType] = useState('closed'); + + return ( + setType('closed'), + }} + > + {children} + + ); +}; + +export function useAside() { + const aside = useContext(AsideContext); + if (!aside) { + throw new Error('useAside must be used within an AsideProvider'); + } + return aside; +} + +/** @typedef {'search' | 'cart' | 'mobile' | 'closed'} AsideType */ +/** + * @typedef {{ + * type: AsideType; + * open: (mode: AsideType) => void; + * close: () => void; + * }} AsideContextValue + */ + +/** @typedef {import('react').ReactNode} ReactNode */ diff --git a/app/components/Cart.jsx b/app/components/Cart.jsx new file mode 100644 index 0000000..131bcc8 --- /dev/null +++ b/app/components/Cart.jsx @@ -0,0 +1,369 @@ +import {CartForm, Image, Money, useOptimisticCart} from '@shopify/hydrogen'; +import {Link} from '@remix-run/react'; +import {useVariantUrl} from '~/lib/variants'; + +/** + * @param {CartMainProps} + */ +export function CartMain({layout, cart: originalCart}) { + const cart = useOptimisticCart(originalCart); + + const linesCount = Boolean(cart?.lines?.nodes?.length || 0); + const withDiscount = + cart && + Boolean(cart?.discountCodes?.filter((code) => code.applicable)?.length); + const className = `cart-main ${withDiscount ? 'with-discount' : ''}`; + + return ( +
+
+ ); +} + +/** + * @param {{ + * cart: OptimisticCart; + * layout: 'page' | 'aside'; + * }} + */ +function CartDetails({layout, cart}) { + const cartHasItems = !!cart && cart.totalQuantity > 0; + + return ( +
+ + {cartHasItems && ( + + + + + )} +
+ ); +} + +/** + * @param {{ + * layout: CartMainProps['layout']; + * lines: CartLine[]; + * }} + */ +function CartLines({lines, layout}) { + if (!lines) return null; + + return ( +
+
    + {lines.map((line) => ( + + ))} +
+
+ ); +} + +/** + * @param {{ + * layout: CartMainProps['layout']; + * line: CartLine; + * }} + */ +function CartLineItem({layout, line}) { + const {id, merchandise} = line; + const {product, title, image, selectedOptions} = merchandise; + const lineItemUrl = useVariantUrl(product.handle, selectedOptions); + + return ( +
  • + {image && ( + {title} + )} + +
    + { + if (layout === 'aside') { + // close the drawer + window.location.href = lineItemUrl; + } + }} + > +

    + {product.title} +

    + + +
      + {selectedOptions.map((option) => ( +
    • + + {option.name}: {option.value} + +
    • + ))} +
    + +
    +
  • + ); +} + +/** + * @param {{checkoutUrl: string}} + */ +function CartCheckoutActions({checkoutUrl}) { + if (!checkoutUrl) return null; + + return ( + + ); +} + +/** + * @param {{ + * children?: React.ReactNode; + * cost: CartApiQueryFragment['cost']; + * layout: CartMainProps['layout']; + * }} + */ +export function CartSummary({cost, layout, children = null}) { + const className = + layout === 'page' ? 'cart-summary-page' : 'cart-summary-aside'; + + return ( +
    +

    Totals

    +
    +
    Subtotal
    +
    + {cost?.subtotalAmount?.amount ? ( + + ) : ( + '-' + )} +
    +
    + {children} +
    + ); +} + +/** + * @param {{ + * lineIds: string[]; + * disabled: boolean; + * }} + */ +function CartLineRemoveButton({lineIds, disabled}) { + return ( + + + + ); +} + +/** + * @param {{line: CartLine}} + */ +function CartLineQuantity({line}) { + if (!line || typeof line?.quantity === 'undefined') return null; + const {id: lineId, quantity, isOptimistic} = line; + const prevQuantity = Number(Math.max(0, quantity - 1).toFixed(0)); + const nextQuantity = Number((quantity + 1).toFixed(0)); + + return ( +
    + Quantity: {quantity}    + + + +   + + + +   + +
    + ); +} + +/** + * @param {{ + * line: CartLine; + * priceType?: 'regular' | 'compareAt'; + * [key: string]: any; + * }} + */ +function CartLinePrice({line, priceType = 'regular', ...passthroughProps}) { + if (!line?.cost?.amountPerQuantity || !line?.cost?.totalAmount) + return
     
    ; + + const moneyV2 = + priceType === 'regular' + ? line.cost.totalAmount + : line.cost.compareAtAmountPerQuantity; + + if (moneyV2 == null) { + return
     
    ; + } + + return ( +
    + +
    + ); +} + +/** + * @param {{ + * hidden: boolean; + * layout?: CartMainProps['layout']; + * }} + */ +export function CartEmpty({hidden = false, layout = 'aside'}) { + return ( + + ); +} + +/** + * @param {{ + * discountCodes: CartApiQueryFragment['discountCodes']; + * }} + */ +function CartDiscounts({discountCodes}) { + const codes = + discountCodes + ?.filter((discount) => discount.applicable) + ?.map(({code}) => code) || []; + + return ( +
    + {/* Have existing discount, display it with a remove option */} + + + {/* Show an input to apply a discount */} + +
    + +   + +
    +
    +
    + ); +} + +/** + * @param {{ + * discountCodes?: string[]; + * children: React.ReactNode; + * }} + */ +function UpdateDiscountForm({discountCodes, children}) { + return ( + + {children} + + ); +} + +/** + * @param {{ + * children: React.ReactNode; + * lines: CartLineUpdateInput[]; + * }} + */ +function CartLineUpdateButton({children, lines}) { + return ( + + {children} + + ); +} + +/** @typedef {OptimisticCart['lines']['nodes'][0]} CartLine */ +/** + * @typedef {{ + * cart: CartApiQueryFragment | null; + * layout: 'page' | 'aside'; + * }} CartMainProps + */ + +/** @typedef {import('@shopify/hydrogen').OptimisticCart} OptimisticCart */ +/** @typedef {import('@shopify/hydrogen/storefront-api-types').CartLineUpdateInput} CartLineUpdateInput */ +/** @typedef {import('storefrontapi.generated').CartApiQueryFragment} CartApiQueryFragment */ diff --git a/app/components/Footer.jsx b/app/components/Footer.jsx new file mode 100644 index 0000000..edd729f --- /dev/null +++ b/app/components/Footer.jsx @@ -0,0 +1,130 @@ +import {Suspense} from 'react'; +import {Await, NavLink} from '@remix-run/react'; + +/** + * @param {FooterProps} + */ +export function Footer({footer: footerPromise, header, publicStoreDomain}) { + return ( + + + {(footer) => ( +
    + {footer?.menu && header.shop.primaryDomain?.url && ( + + )} +
    + )} +
    +
    + ); +} + +/** + * @param {{ + * menu: FooterQuery['menu']; + * primaryDomainUrl: FooterProps['header']['shop']['primaryDomain']['url']; + * publicStoreDomain: string; + * }} + */ +function FooterMenu({menu, primaryDomainUrl, publicStoreDomain}) { + return ( + + ); +} + +const FALLBACK_FOOTER_MENU = { + id: 'gid://shopify/Menu/199655620664', + items: [ + { + id: 'gid://shopify/MenuItem/461633060920', + resourceId: 'gid://shopify/ShopPolicy/23358046264', + tags: [], + title: 'Privacy Policy', + type: 'SHOP_POLICY', + url: '/policies/privacy-policy', + items: [], + }, + { + id: 'gid://shopify/MenuItem/461633093688', + resourceId: 'gid://shopify/ShopPolicy/23358013496', + tags: [], + title: 'Refund Policy', + type: 'SHOP_POLICY', + url: '/policies/refund-policy', + items: [], + }, + { + id: 'gid://shopify/MenuItem/461633126456', + resourceId: 'gid://shopify/ShopPolicy/23358111800', + tags: [], + title: 'Shipping Policy', + type: 'SHOP_POLICY', + url: '/policies/shipping-policy', + items: [], + }, + { + id: 'gid://shopify/MenuItem/461633159224', + resourceId: 'gid://shopify/ShopPolicy/23358079032', + tags: [], + title: 'Terms of Service', + type: 'SHOP_POLICY', + url: '/policies/terms-of-service', + items: [], + }, + ], +}; + +/** + * @param {{ + * isActive: boolean; + * isPending: boolean; + * }} + */ +function activeLinkStyle({isActive, isPending}) { + return { + fontWeight: isActive ? 'bold' : undefined, + color: isPending ? 'grey' : 'white', + }; +} + +/** + * @typedef {Object} FooterProps + * @property {Promise} footer + * @property {HeaderQuery} header + * @property {string} publicStoreDomain + */ + +/** @typedef {import('storefrontapi.generated').FooterQuery} FooterQuery */ +/** @typedef {import('storefrontapi.generated').HeaderQuery} HeaderQuery */ diff --git a/app/components/Header.jsx b/app/components/Header.jsx new file mode 100644 index 0000000..16926da --- /dev/null +++ b/app/components/Header.jsx @@ -0,0 +1,240 @@ +import {Suspense} from 'react'; +import {Await, NavLink} from '@remix-run/react'; +import {useAnalytics} from '@shopify/hydrogen'; +import {useAside} from '~/components/Aside'; + +/** + * @param {HeaderProps} + */ +export function Header({header, isLoggedIn, cart, publicStoreDomain}) { + const {shop, menu} = header; + return ( +
    + + {shop.name} + + + +
    + ); +} + +/** + * @param {{ + * menu: HeaderProps['header']['menu']; + * primaryDomainUrl: HeaderProps['header']['shop']['primaryDomain']['url']; + * viewport: Viewport; + * publicStoreDomain: HeaderProps['publicStoreDomain']; + * }} + */ +export function HeaderMenu({ + menu, + primaryDomainUrl, + viewport, + publicStoreDomain, +}) { + const className = `header-menu-${viewport}`; + + function closeAside(event) { + if (viewport === 'mobile') { + event.preventDefault(); + window.location.href = event.currentTarget.href; + } + } + + return ( + + ); +} + +/** + * @param {Pick} + */ +function HeaderCtas({isLoggedIn, cart}) { + return ( + + ); +} + +function HeaderMenuMobileToggle() { + const {open} = useAside(); + return ( + + ); +} + +function SearchToggle() { + const {open} = useAside(); + return ( + + ); +} + +/** + * @param {{count: number}} + */ +function CartBadge({count}) { + const {open} = useAside(); + const {publish, shop, cart, prevCart} = useAnalytics(); + + return ( + { + e.preventDefault(); + open('cart'); + publish('cart_viewed', { + cart, + prevCart, + shop, + url: window.location.href || '', + }); + }} + > + Cart {count} + + ); +} + +/** + * @param {Pick} + */ +function CartToggle({cart}) { + return ( + }> + + {(cart) => { + if (!cart) return ; + return ; + }} + + + ); +} + +const FALLBACK_HEADER_MENU = { + id: 'gid://shopify/Menu/199655587896', + items: [ + { + id: 'gid://shopify/MenuItem/461609500728', + resourceId: null, + tags: [], + title: 'Collections', + type: 'HTTP', + url: '/collections', + items: [], + }, + { + id: 'gid://shopify/MenuItem/461609533496', + resourceId: null, + tags: [], + title: 'Blog', + type: 'HTTP', + url: '/blogs/journal', + items: [], + }, + { + id: 'gid://shopify/MenuItem/461609566264', + resourceId: null, + tags: [], + title: 'Policies', + type: 'HTTP', + url: '/policies', + items: [], + }, + { + id: 'gid://shopify/MenuItem/461609599032', + resourceId: 'gid://shopify/Page/92591030328', + tags: [], + title: 'About', + type: 'PAGE', + url: '/pages/about', + items: [], + }, + ], +}; + +/** + * @param {{ + * isActive: boolean; + * isPending: boolean; + * }} + */ +function activeLinkStyle({isActive, isPending}) { + return { + fontWeight: isActive ? 'bold' : undefined, + color: isPending ? 'grey' : 'black', + }; +} + +/** @typedef {'desktop' | 'mobile'} Viewport */ +/** + * @typedef {Object} HeaderProps + * @property {HeaderQuery} header + * @property {Promise} cart + * @property {Promise} isLoggedIn + * @property {string} publicStoreDomain + */ + +/** @typedef {import('@shopify/hydrogen').CartViewPayload} CartViewPayload */ +/** @typedef {import('storefrontapi.generated').HeaderQuery} HeaderQuery */ +/** @typedef {import('storefrontapi.generated').CartApiQueryFragment} CartApiQueryFragment */ diff --git a/app/components/PageLayout.jsx b/app/components/PageLayout.jsx new file mode 100644 index 0000000..c373522 --- /dev/null +++ b/app/components/PageLayout.jsx @@ -0,0 +1,132 @@ +import {Await} from '@remix-run/react'; +import {Suspense} from 'react'; +import {Aside} from '~/components/Aside'; +import {Footer} from '~/components/Footer'; +import {Header, HeaderMenu} from '~/components/Header'; +import {CartMain} from '~/components/Cart'; +import { + PredictiveSearchForm, + PredictiveSearchResults, +} from '~/components/Search'; + +/** + * @param {PageLayoutProps} + */ +export function PageLayout({ + cart, + children = null, + footer, + header, + isLoggedIn, + publicStoreDomain, +}) { + return ( + + + + + {header && ( +
    + )} +
    {children}
    +