diff --git a/best-cigars-guide/blocks/footer/footer.js b/best-cigars-guide/blocks/footer/footer.js
index 93d9828..1a32f83 100644
--- a/best-cigars-guide/blocks/footer/footer.js
+++ b/best-cigars-guide/blocks/footer/footer.js
@@ -1,6 +1,6 @@
import { getMetadata } from '../../scripts/aem.js';
import { loadFragment } from '../fragment/fragment.js';
-import { isInternal } from '../../scripts/scripts.js';
+import { isInternal, isCategory } from '../../scripts/scripts.js';
import { addLdJsonScript } from '../../scripts/linking-data.js';
function buildLdJson(container) {
@@ -19,7 +19,7 @@ function buildLdJson(container) {
};
// Change type for category pages
- if (document.querySelector('.article-list-container')) {
+ if (isCategory()) {
ldJson['@type'] = 'CollectionPage';
}
diff --git a/best-cigars-guide/blocks/item/item.css b/best-cigars-guide/blocks/item/item.css
new file mode 100644
index 0000000..636fe07
--- /dev/null
+++ b/best-cigars-guide/blocks/item/item.css
@@ -0,0 +1,73 @@
+.item-wrapper {
+ border-bottom: 1px dashed #ccc;
+ margin-bottom: 40px;
+ padding-bottom: 45px;
+ font-size: 0.75em;
+ font-weight: 300;
+}
+
+.item-wrapper h3 {
+ margin-bottom: 25px;
+ text-align: center;
+ font-size: var(--heading-font-size-s);
+}
+
+.item-wrapper a {
+ display: block;
+ text-align: center;
+}
+
+.item-wrapper img {
+ max-height: 75px;
+ width: auto;
+ margin-bottom: 25px;
+ text-align: center;
+}
+
+.item-wrapper .item-stats {
+ display: flex;
+ justify-content: space-between;
+ flex-wrap: wrap;
+ margin: 30px auto;
+ width: 90%;
+}
+
+.item-wrapper .item-stat {
+ padding-right: 10px;
+}
+
+.item-wrapper .item-stat .label {
+ font-weight: bold;
+}
+
+.item-wrapper .item-buy-now a {
+ font-weight: 600;
+ text-decoration: none;
+ display: inline-block;
+ box-sizing: border-box;
+ width: auto;
+ padding: 10px 25px 9px;
+ background: #177abb;
+ border-bottom: 1px solid #035890;
+ color: #fff;
+ border-radius: 4px;
+ transition: background-color .15s;
+}
+
+.item-wrapper .item-buy-now a:hover {
+ background: #0d67a2;
+}
+
+.item-wrapper .item-subinfo {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ width: 280px;
+ margin: 0 auto;
+}
+
+.item-wrapper .item-star-rating img {
+ width: 25px;
+ height: 25px;
+ margin: 0;
+}
diff --git a/best-cigars-guide/blocks/item/item.js b/best-cigars-guide/blocks/item/item.js
new file mode 100644
index 0000000..55cab3b
--- /dev/null
+++ b/best-cigars-guide/blocks/item/item.js
@@ -0,0 +1,110 @@
+/**
+ * parse block row data into a js object
+ * @param block
+ * @returns {{}}
+ */
+function parseData(block) {
+ const rows = block.children;
+ const data = {};
+
+ // eslint-disable-next-line no-plusplus
+ for (let i = 0; i < rows.length; i++) {
+ const fieldName = rows[i].firstElementChild.textContent;
+
+ if (fieldName === 'Image') {
+ data[fieldName] = rows[i].lastElementChild.innerHTML;
+ } else if (fieldName === 'Rating') {
+ data[fieldName] = Number(rows[i].lastElementChild.textContent);
+ } else {
+ data[fieldName] = rows[i].lastElementChild.textContent;
+ }
+ }
+
+ return data;
+}
+
+/**
+ * render rating stats html
+ * @param data
+ */
+function renderRatingStars(data) {
+ let output = '';
+
+ // eslint-disable-next-line no-plusplus
+ for (let i = 0; i < 5; i++) {
+ if (i + 0.5 === data.Rating) {
+ output += '';
+ } else if (i < data.Rating) {
+ output += '';
+ } else {
+ output += '';
+ }
+ }
+
+ return output;
+}
+
+/**
+ * render individual item stats
+ * @param data
+ * @returns {string}
+ */
+function renderStats(data) {
+ // list of possible stat fields from block data
+ const stats = [
+ 'Country',
+ 'Strength',
+ 'Wrapper',
+ 'Color',
+ ];
+
+ let output = '';
+ // eslint-disable-next-line no-plusplus
+ for (let i = 0; i < stats.length; i++) {
+ if (stats[i] in data) {
+ output += `
+
+
${stats[i]}
+
${data[stats[i]]}
+
+ `;
+ }
+ }
+
+ return output;
+}
+
+function render(data) {
+ const ratingLabel = data.Rating ? `Rated ${data.Rating} out of 5 stars.` : 'No ratings yet.';
+
+ return `
+ ${data.Name}
+
+ ${data.Image}
+
+
+
${data.Description}
+
+ ${renderStats(data)}
+
+
+
+ ${renderRatingStars(data)}
+
+
+
+
+ `;
+}
+
+/**
+ * loads and decorates the item
+ * @param {Element} block The item element
+ */
+export default async function decorate(block) {
+ const data = parseData(block);
+ block.innerHTML = render(data);
+ return block;
+}
diff --git a/best-cigars-guide/blocks/nav/nav.css b/best-cigars-guide/blocks/nav/nav.css
index faa101b..eb176ed 100644
--- a/best-cigars-guide/blocks/nav/nav.css
+++ b/best-cigars-guide/blocks/nav/nav.css
@@ -3,8 +3,9 @@
display: flex;
justify-content: space-between;
align-items: center;
- margin-bottom: 20px;
- padding: 10px 0;
+ padding: 50px 1rem 15px;
+ max-width: var(--content-width);
+ margin: 0 auto 20px;
}
/* Breadcrumb styling */
@@ -68,6 +69,7 @@
.nav-row {
flex-direction: column; /* Stack items vertically on small screens */
align-items: center;
+ padding: 10px 16px;
}
.breadcrumb,
diff --git a/best-cigars-guide/blocks/nav/nav.js b/best-cigars-guide/blocks/nav/nav.js
index 73b9731..16bc128 100644
--- a/best-cigars-guide/blocks/nav/nav.js
+++ b/best-cigars-guide/blocks/nav/nav.js
@@ -122,8 +122,8 @@ export default function decorate(block) {
block.remove();
// Create nav
- const startingTag = document.querySelector('body > main > div');
- const navDiv = document.createElement('div');
+ const startingTag = document.querySelector('body > header');
+ const navDiv = document.createElement('nav');
navDiv.className = 'nav-row';
// Create Breadcrumbs
@@ -142,5 +142,5 @@ export default function decorate(block) {
awaitCategoriesDropdown();
// Append nav to the dom
- startingTag.prepend(navDiv);
+ startingTag.after(navDiv);
}
diff --git a/best-cigars-guide/blocks/sidebar/sidebar.css b/best-cigars-guide/blocks/sidebar/sidebar.css
new file mode 100644
index 0000000..623c93a
--- /dev/null
+++ b/best-cigars-guide/blocks/sidebar/sidebar.css
@@ -0,0 +1,49 @@
+.article-wrapper {
+ display: flex;
+ max-width: var(--content-width);
+ margin: auto;
+ justify-content: space-between;
+ padding: 0 1rem;
+}
+
+.article-wrapper .section {
+ padding: 0;
+ width: 64%;
+}
+
+.article-wrapper aside {
+ width: 30%;
+ max-width: 315px;
+}
+
+aside h3 {
+ font-size: 0.9em;
+ margin: 0 0 1.2em;
+ font-weight: 700;
+}
+
+aside ul {
+ list-style: none;
+ padding: 0;
+}
+
+aside li {
+ margin: 0 0 12px;
+ font-weight: 300;
+ font-size: 0.7em;
+}
+
+@media (max-width: 600px) {
+ .article-wrapper {
+ display: block;
+ }
+
+ .article-wrapper .section {
+ width: 100%;
+ }
+
+ .article-wrapper aside {
+ width: 100%;
+ max-width: 100%;
+ }
+}
diff --git a/best-cigars-guide/blocks/sidebar/sidebar.js b/best-cigars-guide/blocks/sidebar/sidebar.js
new file mode 100644
index 0000000..2752481
--- /dev/null
+++ b/best-cigars-guide/blocks/sidebar/sidebar.js
@@ -0,0 +1,64 @@
+import { fetchCategoryList } from '../../scripts/scripts.js';
+
+function getRelatedArticles() {
+ const wrap = document.createElement('div');
+ wrap.className = 'sidebar-related-articles';
+
+ const heading = document.createElement('h3');
+ heading.textContent = 'Related Articles';
+ wrap.append(heading);
+
+ const list = document.createElement('ul');
+
+ // todo: related article magic 🪄
+ list.innerHTML = 'Dummy list itemDummy list item 2';
+
+ wrap.append(list);
+
+ return wrap;
+}
+
+async function getCategories() {
+ const wrap = document.createElement('div');
+ wrap.className = 'sidebar-categories';
+
+ const heading = document.createElement('h3');
+ heading.textContent = 'CATEGORY';
+ wrap.append(heading);
+
+ const currentCategoryPath = window.location.pathname.split('/').slice(0, 3).join('/');
+ const categoriesList = await fetchCategoryList();
+ // get the current category name
+ categoriesList.forEach((category) => {
+ const categoryPath = category.path.split('/')
+ .slice(0, 3)
+ .join('/');
+
+ if (categoryPath === currentCategoryPath) {
+ heading.innerText = category.path
+ .split('/')
+ .pop()
+ .replace(/-/g, ' ')
+ .replace(/\b\w/g, (char) => char.toUpperCase());
+ }
+ });
+
+ const list = document.createElement('ul');
+
+ // todo: fetch sub-categories from index
+ list.innerHTML = 'Dummy list itemDummy list item 2';
+
+ wrap.append(list);
+
+ return wrap;
+}
+
+export default async function decorate(block) {
+ const categories = await getCategories();
+ block.append(categories);
+
+ const relatedArticles = getRelatedArticles();
+ block.append(relatedArticles);
+
+ return block;
+}
diff --git a/best-cigars-guide/icons/star-empty.png b/best-cigars-guide/icons/star-empty.png
new file mode 100644
index 0000000..a28fbb4
Binary files /dev/null and b/best-cigars-guide/icons/star-empty.png differ
diff --git a/best-cigars-guide/icons/star-half.png b/best-cigars-guide/icons/star-half.png
new file mode 100644
index 0000000..2b78ab9
Binary files /dev/null and b/best-cigars-guide/icons/star-half.png differ
diff --git a/best-cigars-guide/icons/star.png b/best-cigars-guide/icons/star.png
new file mode 100644
index 0000000..098181d
Binary files /dev/null and b/best-cigars-guide/icons/star.png differ
diff --git a/best-cigars-guide/scripts/scripts.js b/best-cigars-guide/scripts/scripts.js
index 3a0ffc2..330918e 100644
--- a/best-cigars-guide/scripts/scripts.js
+++ b/best-cigars-guide/scripts/scripts.js
@@ -1,6 +1,20 @@
/* eslint-disable max-len */
// eslint-disable-next-line object-curly-newline
-import { sampleRUM, buildBlock, loadHeader, loadFooter, decorateButtons, decorateIcons, decorateSections, decorateBlocks, decorateTemplateAndTheme, waitForLCP, loadBlocks, loadCSS } from './aem.js';
+import {
+ sampleRUM,
+ buildBlock,
+ loadHeader,
+ loadFooter,
+ decorateButtons,
+ decorateIcons,
+ decorateSections,
+ decorateBlocks,
+ decorateTemplateAndTheme,
+ waitForLCP,
+ loadBlocks,
+ loadCSS,
+ decorateBlock,
+} from './aem.js';
const LCP_BLOCKS = []; // add your LCP blocks to the list
const CATEGORY_INDEX_PATH = '/best-cigars-guide/index/category-index.json';
@@ -47,6 +61,34 @@ function buildHeroBlock(main) {
}
}
+/**
+ * check if this is a category listing page
+ */
+export function isCategory() {
+ return !!document.querySelector('.article-list-container, main.error');
+}
+
+/**
+ * builds sidebar block appends to main
+ * @param {Element} main The container element
+ */
+function buildSidebarBlock(main) {
+ const sidebarBlock = document.querySelector('main aside');
+
+ if (!isCategory() && !sidebarBlock && main.tagName === 'MAIN') {
+ const container = document.querySelector('main');
+ const sidebar = document.createElement('aside');
+ sidebar.className = 'sidebar-wrapper';
+
+ const block = buildBlock('sidebar', '');
+ sidebar.append(block);
+ decorateBlock(block);
+
+ container.classList.add('article-wrapper');
+ container.append(sidebar);
+ }
+}
+
/**
* load fonts.css and set a session storage flag
*/
@@ -84,6 +126,7 @@ export function decorateMain(main) {
buildAutoBlocks(main);
decorateSections(main);
decorateBlocks(main);
+ buildSidebarBlock(main);
}
/**
diff --git a/best-cigars-guide/styles/styles.css b/best-cigars-guide/styles/styles.css
index ba20c72..0c6bd05 100644
--- a/best-cigars-guide/styles/styles.css
+++ b/best-cigars-guide/styles/styles.css
@@ -12,8 +12,8 @@
:root {
/* colors */
- --link-color: #035fe6;
- --link-hover-color: #136ff6;
+ --link-color: #177abb;
+ --link-hover-color: #177abb;
--header-color: #2c2c2c;
--paragraph-color: #4a4a4a;
--background-color: white;
@@ -242,12 +242,12 @@ main img {
/* sections */
main .section {
- padding: 16px;
+ padding: 0 16px 16px;
}
@media (min-width: 600px) {
main .section {
- padding: 32px;
+ padding: 0 32px 32px;
}
}
@@ -263,3 +263,13 @@ main .section.light,
main .section.highlight {
background-color: var(--light-color);
}
+
+.default-content-wrapper {
+ font-size: 0.75em;
+ font-weight: 300;
+}
+
+.default-content-wrapper h1 {
+ font-weight: 700;
+ margin: 0 0 1.2em;
+}