From c8dfe553649a3555941717d357794af100446ee5 Mon Sep 17 00:00:00 2001 From: devaquila Date: Tue, 2 Feb 2021 15:13:55 +0100 Subject: [PATCH 1/3] Provider AquilaCMS --- .env.sample | 4 ++ package.json | 1 + pages/_app.js | 6 +++ pages/categories.js | 31 ++++++----- provider/aquila-cms/categoryProvider.js | 10 ++++ provider/aquila-cms/currencyProvider.js | 3 ++ provider/aquila-cms/inventoryByCategory.js | 20 +++++++ provider/aquila-cms/inventoryProvider.js | 62 ++++++++++++++++++++++ utils/categoryProvider.js | 5 ++ utils/inventoryByCategory.js | 6 +++ utils/inventoryProvider.js | 4 ++ yarn.lock | 12 +++++ 12 files changed, 150 insertions(+), 14 deletions(-) create mode 100644 .env.sample create mode 100644 provider/aquila-cms/categoryProvider.js create mode 100644 provider/aquila-cms/currencyProvider.js create mode 100644 provider/aquila-cms/inventoryByCategory.js create mode 100644 provider/aquila-cms/inventoryProvider.js diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000..1132b49 --- /dev/null +++ b/.env.sample @@ -0,0 +1,4 @@ +NEXT_PUBLIC_PROVIDER=aquila-cms +NEXT_PUBLIC_API_URL=https://dem01.aquila-cms.com/api +NEXT_PUBLIC_IMG_URL=https://dem01.aquila-cms.com + diff --git a/package.json b/package.json index 1911a9d..c692dd8 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "@stripe/react-stripe-js": "^1.1.2", "@stripe/stripe-js": "^1.11.0", "autoprefixer": "^10.1.0", + "axios": "^0.21.1", "next": "10.0.4", "postcss": "^8.2.2", "react": "17.0.1", diff --git a/pages/_app.js b/pages/_app.js index d72b474..59308b2 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -1,8 +1,14 @@ import '../styles/globals.css' import Layout from '../layouts/layout' import fetchCategories from '../utils/categoryProvider' +import axios from 'axios'; function Ecommerce({ Component, pageProps, categories }) { + + if(process.env.NEXT_PUBLIC_API_URL) { + axios.defaults.baseURL = process.env.NEXT_PUBLIC_API_URL; + } + return ( diff --git a/pages/categories.js b/pages/categories.js index 58d7e92..8701b32 100644 --- a/pages/categories.js +++ b/pages/categories.js @@ -46,21 +46,24 @@ export async function getStaticProps() { const inventory = await fetchInventory() const inventoryCategories = inventory.reduce((acc, next) => { const categories = next.categories - categories.forEach(c => { - const index = acc.findIndex(item => item.name === c) - if (index !== -1) { - const item = acc[index] - item.itemCount = item.itemCount + 1 - acc[index] = item - } else { - const item = { - name: c, - image: next.image, - itemCount: 1 + if(categories) { + categories.forEach(c => { + const index = acc.findIndex(item => item.name === c) + if (index !== -1) { + const item = acc[index] + item.itemCount = item.itemCount + 1 + acc[index] = item + } else { + const item = { + name: c, + image: next.image, + itemCount: 1 + } + + acc.push(item) } - acc.push(item) - } - }) + }) + } return acc }, []) diff --git a/provider/aquila-cms/categoryProvider.js b/provider/aquila-cms/categoryProvider.js new file mode 100644 index 0000000..3b4f3ee --- /dev/null +++ b/provider/aquila-cms/categoryProvider.js @@ -0,0 +1,10 @@ +import axios from 'axios' + +async function fetchCategories () { + const response = await axios.post('/v2/categories', {lang:"en", PostBody: {filter: {'action':'catalog'}, limit: 99}}) + return response.data.datas.map(cat => cat.name) +} + +export default { + fetchCategories +} \ No newline at end of file diff --git a/provider/aquila-cms/currencyProvider.js b/provider/aquila-cms/currencyProvider.js new file mode 100644 index 0000000..31241f2 --- /dev/null +++ b/provider/aquila-cms/currencyProvider.js @@ -0,0 +1,3 @@ +const DENOMINATION = '€' + +export default DENOMINATION \ No newline at end of file diff --git a/provider/aquila-cms/inventoryByCategory.js b/provider/aquila-cms/inventoryByCategory.js new file mode 100644 index 0000000..a26132f --- /dev/null +++ b/provider/aquila-cms/inventoryByCategory.js @@ -0,0 +1,20 @@ +function inventoryByCategory (inventory) { + return inventory.reduce((acc, next) => { + const categories = next.categories + categories.forEach(c => { + const category = c.replace(/-/g," "); // Need to transform for matching datas + if (acc[category]) { + acc[category].items.push(next) + } else { + acc[category] = {} + acc[category].items = [] + acc[category].items.push(next) + } + }) + return acc + }, {}) +} + +export default { + inventoryByCategory +} \ No newline at end of file diff --git a/provider/aquila-cms/inventoryProvider.js b/provider/aquila-cms/inventoryProvider.js new file mode 100644 index 0000000..8733a30 --- /dev/null +++ b/provider/aquila-cms/inventoryProvider.js @@ -0,0 +1,62 @@ +import axios from 'axios' +axios.defaults.baseURL = process.env.NEXT_PUBLIC_API_URL; + +async function fetchInventory(category) { + let aqlPrds = []; + + if(category) { + const catResp = await axios.post('/v2/category', {lang:"en", PostBody: {filter: {['translation.en.name']: {$regex: category.toLowerCase(), $options: "i"}}}}) + + const response = await axios.post('/v2/products/category/' + catResp.data._id, {lang:"en", PostBody: {filter: {}, structure: {['translation.en.description1']: 1, images: 1, ['translation.en.name']: 1, code: 1}, limit: 99}}) + aqlPrds = response.data.datas + } else { + const response = await axios.post('/v2/products', {lang:"en", PostBody: {filter: {}, structure: {images: 1}, limit: 99}}) + aqlPrds = response.data.datas + + } + + return convertProducts(aqlPrds); +} + +// Convert products to the jamestack schema +async function convertProducts(aqlPrds) { + for(const prd of aqlPrds) { + if(prd.price.ati.special) { + prd.price = prd.price.ati.special; + } else { + prd.price = prd.price.ati.normal; + } + prd.brand = ""; + //prd.sku = prd.code; + prd.description = prd.description1.text; + const mainImage = prd.images ? prd.images.find(img => img.default) : null; + prd.image = mainImage ? `${process.env.NEXT_PUBLIC_IMG_URL}/images/products/544x282-80-245,245,245,1/${mainImage._id}/${mainImage.title}${mainImage.extension}` : ''; + + // Get the linked categories + prd.categories = await findCategoriesForThisProduct(prd._id); + } + + return aqlPrds; +} + +// Get all categories (for the productsList) +async function findCategoriesForThisProduct(prd_id) { + const result = await axios.post('/v2/categories', {lang:"en", PostBody: {filter: {action:"catalog"}, structure:{productsList:1}, limit: 99}}); + const allCategories = result.data.datas; + + let prdCategories = []; + for (let j = 0; j < allCategories.length; j++ ) { + const currentCat = allCategories[j]; + for (let index = 0; index < currentCat.productsList.length; index++) { + if(currentCat.productsList[index].id == prd_id) { + prdCategories.push(currentCat.slug.en); + } + } + } + + return prdCategories; +} + +export default { + fetchInventory +} diff --git a/utils/categoryProvider.js b/utils/categoryProvider.js index 8e47448..3b770dc 100644 --- a/utils/categoryProvider.js +++ b/utils/categoryProvider.js @@ -1,6 +1,11 @@ import inventory from './inventory' +import provideraquilacms from '../provider/aquila-cms/categoryProvider' async function fetchCategories () { + if(process.env.NEXT_PUBLIC_PROVIDER === "aquila-cms") { + return provideraquilacms.fetchCategories(); + } + const categories = inventory.reduce((acc, next) => { next.categories.map(category => { if (acc.includes(category)) return diff --git a/utils/inventoryByCategory.js b/utils/inventoryByCategory.js index 3b36839..5d2ce2e 100644 --- a/utils/inventoryByCategory.js +++ b/utils/inventoryByCategory.js @@ -1,4 +1,10 @@ +import provideraquilacms from '../provider/aquila-cms/inventoryByCategory' + function inventoryByCategory (inventory) { + if(process.env.NEXT_PUBLIC_PROVIDER === "aquila-cms") { + return provideraquilacms.inventoryByCategory(inventory); + } + return inventory.reduce((acc, next) => { const categories = next.categories categories.forEach(c => { diff --git a/utils/inventoryProvider.js b/utils/inventoryProvider.js index 4f1f815..06af558 100644 --- a/utils/inventoryProvider.js +++ b/utils/inventoryProvider.js @@ -1,4 +1,5 @@ import inventory from './inventory' +import provideraquilacms from '../provider/aquila-cms/inventoryProvider' /* Inventory items should adhere to the following schema: @@ -17,6 +18,9 @@ type Product { async function fetchInventory() { // const inventory = API.get(apiUrl) + if(process.env.NEXT_PUBLIC_PROVIDER === "aquila-cms") { + return provideraquilacms.fetchInventory(); + } return Promise.resolve(inventory) } diff --git a/yarn.lock b/yarn.lock index b7c36f8..7d50997 100644 --- a/yarn.lock +++ b/yarn.lock @@ -549,6 +549,13 @@ autoprefixer@^10.1.0: normalize-range "^0.1.2" postcss-value-parser "^4.1.0" +axios@^0.21.1: + version "0.21.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" + integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA== + dependencies: + follow-redirects "^1.10.0" + babel-plugin-syntax-jsx@6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" @@ -1708,6 +1715,11 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" +follow-redirects@^1.10.0: + version "1.13.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.2.tgz#dd73c8effc12728ba5cf4259d760ea5fb83e3147" + integrity sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA== + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" From 3ed0487e3f75ff0cc06ed4cab5fe7b1523e81f5f Mon Sep 17 00:00:00 2001 From: devaquila Date: Wed, 3 Feb 2021 01:40:53 +0100 Subject: [PATCH 2/3] Dynamic import provider --- pages/_app.js | 8 +++----- provider/aquila-cms/currencyProvider.js | 3 --- utils/categoryProvider.js | 7 ++++--- utils/inventoryByCategory.js | 9 +++++---- utils/inventoryForCategory.js | 2 +- utils/inventoryProvider.js | 8 ++++---- 6 files changed, 17 insertions(+), 20 deletions(-) delete mode 100644 provider/aquila-cms/currencyProvider.js diff --git a/pages/_app.js b/pages/_app.js index 59308b2..f894f3d 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -3,12 +3,10 @@ import Layout from '../layouts/layout' import fetchCategories from '../utils/categoryProvider' import axios from 'axios'; +if(process.env.NEXT_PUBLIC_API_URL) { + axios.defaults.baseURL = process.env.NEXT_PUBLIC_API_URL; +} function Ecommerce({ Component, pageProps, categories }) { - - if(process.env.NEXT_PUBLIC_API_URL) { - axios.defaults.baseURL = process.env.NEXT_PUBLIC_API_URL; - } - return ( diff --git a/provider/aquila-cms/currencyProvider.js b/provider/aquila-cms/currencyProvider.js deleted file mode 100644 index 31241f2..0000000 --- a/provider/aquila-cms/currencyProvider.js +++ /dev/null @@ -1,3 +0,0 @@ -const DENOMINATION = '€' - -export default DENOMINATION \ No newline at end of file diff --git a/utils/categoryProvider.js b/utils/categoryProvider.js index 3b770dc..2945c6b 100644 --- a/utils/categoryProvider.js +++ b/utils/categoryProvider.js @@ -1,9 +1,10 @@ import inventory from './inventory' -import provideraquilacms from '../provider/aquila-cms/categoryProvider' async function fetchCategories () { - if(process.env.NEXT_PUBLIC_PROVIDER === "aquila-cms") { - return provideraquilacms.fetchCategories(); + // Is provider configured ? + if(process.env.NEXT_PUBLIC_PROVIDER) { + const provider = await import(`../provider/${process.env.NEXT_PUBLIC_PROVIDER}/categoryProvider`); + return provider.default.fetchCategories(); } const categories = inventory.reduce((acc, next) => { diff --git a/utils/inventoryByCategory.js b/utils/inventoryByCategory.js index 5d2ce2e..5909aea 100644 --- a/utils/inventoryByCategory.js +++ b/utils/inventoryByCategory.js @@ -1,8 +1,9 @@ -import provideraquilacms from '../provider/aquila-cms/inventoryByCategory' -function inventoryByCategory (inventory) { - if(process.env.NEXT_PUBLIC_PROVIDER === "aquila-cms") { - return provideraquilacms.inventoryByCategory(inventory); +async function inventoryByCategory (inventory) { + // Is provider configured ? + if(process.env.NEXT_PUBLIC_PROVIDER) { + const provider = await import(`../provider/${process.env.NEXT_PUBLIC_PROVIDER}/inventoryByCategory`); + return provider.default.inventoryByCategory(inventory); } return inventory.reduce((acc, next) => { diff --git a/utils/inventoryForCategory.js b/utils/inventoryForCategory.js index e86bc00..adcff43 100644 --- a/utils/inventoryForCategory.js +++ b/utils/inventoryForCategory.js @@ -3,7 +3,7 @@ import { inventoryByCategory } from './inventoryByCategory' async function inventoryForCategory (category) { const inventory = await fetchInventory() - const byCategory = inventoryByCategory(inventory) + const byCategory = await inventoryByCategory(inventory) return byCategory[category].items } diff --git a/utils/inventoryProvider.js b/utils/inventoryProvider.js index 06af558..0de677b 100644 --- a/utils/inventoryProvider.js +++ b/utils/inventoryProvider.js @@ -1,5 +1,4 @@ import inventory from './inventory' -import provideraquilacms from '../provider/aquila-cms/inventoryProvider' /* Inventory items should adhere to the following schema: @@ -17,9 +16,10 @@ type Product { */ async function fetchInventory() { - // const inventory = API.get(apiUrl) - if(process.env.NEXT_PUBLIC_PROVIDER === "aquila-cms") { - return provideraquilacms.fetchInventory(); + // Is provider configured ? + if(process.env.NEXT_PUBLIC_PROVIDER) { + const provider = await import(`../provider/${process.env.NEXT_PUBLIC_PROVIDER}/inventoryProvider`); + return provider.default.fetchInventory(); } return Promise.resolve(inventory) } From 634d9bdbf484b6459bdc2bf8aea5c091780fd9f1 Mon Sep 17 00:00:00 2001 From: bertrandev Date: Mon, 8 Mar 2021 15:43:46 +0100 Subject: [PATCH 3/3] [Fix] Remove axios for category --- .gitignore | 1 + provider/aquila-cms/categoryProvider.js | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 4be9d59..bc1fa6d 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ yarn-debug.log* yarn-error.log* # local env files +.env .env.local .env.development.local .env.test.local diff --git a/provider/aquila-cms/categoryProvider.js b/provider/aquila-cms/categoryProvider.js index 3b4f3ee..6a9ecc0 100644 --- a/provider/aquila-cms/categoryProvider.js +++ b/provider/aquila-cms/categoryProvider.js @@ -1,8 +1,11 @@ -import axios from 'axios' - async function fetchCategories () { - const response = await axios.post('/v2/categories', {lang:"en", PostBody: {filter: {'action':'catalog'}, limit: 99}}) - return response.data.datas.map(cat => cat.name) + const response = await fetch(process.env.NEXT_PUBLIC_API_URL + '/v2/categories', { + method: 'POST', + body: JSON.stringify({lang:"en", PostBody: {"limit":99, "filter":{"code":"my-products"}, "structure":{"children":1}, "populate":["children"]}}), + headers: {"Content-type": "application/json; charset=UTF-8"} + }) + const data = await response.json(); + return data.datas[0].children.map(cat => cat.name) } export default {