Skip to content

Commit 64cfccd

Browse files
Merge pull request #109 from bitlogic/develop
Merge develop to main
2 parents 76dd0b3 + 23527c0 commit 64cfccd

File tree

25 files changed

+515
-249
lines changed

25 files changed

+515
-249
lines changed

gatsby-config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ module.exports = {
102102
resolve: `gatsby-source-strapi`,
103103
options: {
104104
// apiURL: `http://lb-bitlogic-strapi-dev-48805770.sa-east-1.elb.amazonaws.com:1337`,
105-
// apiURL: `https://strapi.bitlogic.io`,
105+
//apiURL: `https://strapi.bitlogic.io`,
106106
apiURL: process.env.STRAPI_URL,
107107
//apiURL: 'http://127.0.0.1:1337',
108108
queryLimit: 1000,

gatsby-node.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@ const FilterWarningsPlugin = require("webpack-filter-warnings-plugin")
33

44
exports.onCreateWebpackConfig = ({ actions }) => {
55
actions.setWebpackConfig({
6+
resolve: {
7+
extensions: ['.mjs', '.js'],
8+
},
9+
module: {
10+
rules: [
11+
{
12+
test: /\.mjs$/,
13+
include: /node_modules/,
14+
type: 'javascript/auto',
15+
},
16+
],
17+
},
618
plugins: [
719
new FilterWarningsPlugin({
820
exclude: /mini-css-extract-plugin[^]*Conflicting order. Following module has been added:/,
@@ -114,4 +126,33 @@ exports.createPages = async ({ graphql, actions }) => {
114126
},
115127
})
116128
})
129+
130+
// 3) Category pages
131+
const categoryResult = await graphql(`
132+
{
133+
allStrapiEnglishBlogCategory {
134+
nodes {
135+
name
136+
slug
137+
}
138+
}
139+
}
140+
`)
141+
if (categoryResult.errors) {
142+
reporter.panicOnBuild(
143+
"Error creating category pages",
144+
categoryResult.errors
145+
)
146+
}
147+
const categoryTemplate = path.resolve("./src/templates/CategoryPage.js")
148+
categoryResult.data.allStrapiEnglishBlogCategory.nodes.forEach(category => {
149+
const slugLower = category.slug.toLowerCase()
150+
createPage({
151+
path: `/blog/${slugLower}`,
152+
component: categoryTemplate,
153+
context: {
154+
name: category.name,
155+
},
156+
})
157+
})
117158
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"react-dom": "^17.0.1",
3939
"react-flip-toolkit": "^7.0.13",
4040
"react-helmet": "^6.1.0",
41-
"react-icons": "^4.2.0",
41+
"react-icons": "^2.2.7",
4242
"react-lottie": "^1.2.3",
4343
"react-multi-carousel": "^2.8.0",
4444
"react-showdown": "^2.3.1",

src/components/BannerList/BannerList.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export default function BannerList({ data }) {
4141

4242
return (
4343
<div className="container pt-5">
44-
<div className="bannerList d-md-flex flex-row">
44+
<div className="bannerList d-md-flex flex-row" data-nosnippet>
4545
<h2 className="bannerList__title col-md-6 col-xl-6 align-self-center mb-4">
4646
{title}
4747
{contactForm && concactFormAnchor && callToAction && (

src/components/BannerRedirect/BannerRedirect.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { useState, useEffect } from "react"
22
import "./BannerRedirect.scss"
3-
import { MdClose } from "react-icons/md"
3+
4+
import MdClose from "react-icons/lib/md/close"
45

56
function BannerRedirect() {
67
const [isOpen, setIsOpen] = useState(true)
Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,66 @@
11
import React from "react"
22
import { Link } from "gatsby"
3-
// import ReactMarkdown from "react-markdown"
43
import MarkdownView from "react-showdown"
5-
import "./BlogArticle.scss"
6-
import CustomImage from "../../CustomImage/CustomImage"
74
import PropTypes from "prop-types"
5+
import CustomImage from "../../CustomImage/CustomImage"
6+
import "./BlogArticle.scss"
87

9-
const BlogArticle = ({ title, summary, image, slug, text }) => {
10-
11-
12-
return (
13-
<div className="article__container">
14-
<CustomImage
15-
image={image}
16-
alt={image?.alternativeText || title}
17-
className="article__image"
18-
width={140}
19-
height={170}
20-
/>
21-
<div className="article__description">
22-
<h3>{`${title}`}</h3>
23-
<div>
24-
<MarkdownView
25-
markdown={`${summary}`}
26-
dangerouslySetInnerHTML={{ __html: summary }} />
27-
{/* <ReactMarkdown source={`${summary} ...`} /> */}
28-
</div>
29-
<div className="article__link">
30-
<Link to={slug}>
31-
<small>{text}</small>
32-
</Link>
33-
</div>
8+
const BlogArticle = ({
9+
title,
10+
summary,
11+
image,
12+
slug,
13+
text,
14+
destacado = false,
15+
}) => (
16+
<div
17+
className={`article__container${destacado ? ' article--destacado' : ''}`}
18+
data-nosnippet
19+
>
20+
{destacado && (
21+
<span className="article__badge">Destacado</span>
22+
)}
23+
24+
<CustomImage
25+
image={image}
26+
alt={image?.alternativeText || title}
27+
className="article__image"
28+
width={140}
29+
height={170}
30+
/>
31+
32+
<div className="article__description">
33+
<h4 className="article__title">{title}</h4>
34+
<MarkdownView markdown={`${summary}`}
35+
dangerouslySetInnerHTML={{ __html: summary }}
36+
/>
37+
<div className="article__link">
38+
<Link to={slug}>
39+
<small>{text || 'Read this blog'}</small>
40+
</Link>
3441
</div>
3542
</div>
36-
)
37-
}
43+
</div>
44+
)
3845

3946
BlogArticle.propTypes = {
4047
title: PropTypes.string.isRequired,
41-
slug: PropTypes.string.isRequired,
4248
summary: PropTypes.string.isRequired,
43-
text: PropTypes.string,
4449
image: PropTypes.shape({
4550
alternativeText: PropTypes.string,
4651
url: PropTypes.string,
47-
})
52+
localFile: PropTypes.shape({
53+
childImageSharp: PropTypes.shape({
54+
gatsbyImageData: PropTypes.object.isRequired,
55+
}),
56+
}),
57+
}).isRequired,
58+
slug: PropTypes.string.isRequired,
59+
text: PropTypes.string,
60+
destacado: PropTypes.bool,
4861
}
4962

50-
export default BlogArticle
63+
export default BlogArticle;
64+
65+
66+

src/components/BlogPage/BlogContainer.js

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,50 +2,72 @@ import React from "react"
22
import { useBlog } from "../../hooks"
33
import BlogGrid from "./BlogGrid/BlogGrid"
44
import BlogArticle from "./BlogArticle/BlogArticle"
5-
import { Layaout } from ".."
6-
import Banner from "../Banner/Banner"
75
import Seo from "../Seo/Seo"
8-
9-
6+
import Layout from "../layout"
7+
import Banner from "../Banner/Banner"
108
import "./BlogContainer.scss"
119

1210
const Blog = () => {
11+
const { allStrapiBlogCategory, allStrapiArticle, allStrapiBlogPage } = useBlog()
12+
const categorias = allStrapiBlogCategory.nodes
13+
const articulos = allStrapiArticle.nodes
14+
const { seo, banner } = allStrapiBlogPage.nodes[0] || {}
15+
const callToAction = allStrapiBlogPage.nodes[0]?.callToActionArticle
1316

14-
const blogData = useBlog()
15-
const data = blogData?.allStrapiBlogCategory?.nodes
16-
const dataArticles = blogData?.allStrapiArticle?.nodes
17-
const defaultCategory = data[0]?.name
18-
const filterArticle = data.map(category => dataArticles.filter(article => category.name === article?.blog_category?.name || defaultCategory))
19-
const { seo, banner, callToAction } = blogData.allStrapiBlogPage.nodes[0]
17+
// Para cada categoría, tomo los primeros 3 artículos sin lógica de destacados
18+
const articulosPorCategoria = categorias
19+
.map(categoria => {
20+
const articulosCat = articulos
21+
.filter(art => art.blog_category?.slug === categoria.slug)
22+
.sort((a, b) => {
23+
// Primero los destacados (true = 1, false = 0)
24+
if (a.destacado !== b.destacado) {
25+
return a.destacado ? -1 : 1
26+
}
2027

28+
// Si ambos son igual en destacado, ordenar por fecha (más nuevo primero)
29+
const fechaA = new Date(a.publishedAt)
30+
const fechaB = new Date(b.publishedAt)
31+
return fechaB - fechaA
32+
}) // <-- cierra el sort
2133

34+
return {
35+
name: categoria.name,
36+
slug: categoria.slug,
37+
items: articulosCat.slice(0, 3), // Tomar solo los primeros 3
38+
}
39+
})
40+
.filter(grupo => grupo.items.length > 0)
2241
return (
23-
<Layaout>
42+
<Layout>
2443
<Seo
25-
title={seo.pageTitle}
26-
description={seo.pageDescription}
27-
keywords={seo.pageKeywords}
44+
title={seo?.pageTitle}
45+
description={seo?.pageDescription}
46+
keywords={seo?.pageKeywords}
2847
/>
2948
<Banner data={banner} />
30-
{data.length > 0 && (
31-
<div className="blog__container container">
32-
{filterArticle?.map((category, idx) => (
33-
<BlogGrid key={data[idx].name} title={category[0]?.blog_category?.name}>
34-
{category.map(item => (
35-
<BlogArticle
36-
key={item.id}
37-
image={item.image}
38-
title={item.title}
39-
summary={item.summary}
40-
slug={"/blog/" + item.slug}
41-
text={callToAction}
42-
/>
43-
))}
44-
</BlogGrid>
45-
))}
46-
</div>
47-
)}
48-
</Layaout>
49+
50+
<div className="blog__container container">
51+
{articulosPorCategoria.map(({ name, slug, items }) => (
52+
<BlogGrid
53+
key={slug}
54+
title={name}
55+
viewAllHref={`/blog/${slug.toLowerCase()}`}
56+
>
57+
{items.map(item => (
58+
<BlogArticle
59+
key={item.id}
60+
image={item.image || item.imagePage}
61+
title={item.title}
62+
summary={item.summary}
63+
slug={`/blog/${item.slug}`}
64+
text={callToAction}
65+
/>
66+
))}
67+
</BlogGrid>
68+
))}
69+
</div>
70+
</Layout>
4971
)
5072
}
5173

src/components/BlogPage/BlogContainer.scss

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,55 @@
44
width: 100%;
55
padding: 5px 15px 60px;
66
margin-bottom: 0px;
7+
8+
@media (min-width: $breakpoint-md) {
9+
padding: 0 45px;
10+
}
11+
12+
.blog__section {
13+
margin-bottom: 2rem;
14+
15+
&-header {
16+
display: flex;
17+
justify-content: space-between;
18+
align-items: center;
19+
padding: 0.5rem 0;
20+
border-bottom: 4px solid $alt;
21+
22+
.blog__section-title {
23+
font-size: 28px;
24+
color: $primary;
25+
margin: 0;
26+
padding-left: 0.5rem;
27+
}
28+
29+
.blog__view-all {
30+
font-size: 0.9rem;
31+
text-decoration: none;
32+
color: $primary;
33+
transition: filter 0.2s;
34+
35+
&:hover {
36+
filter: brightness(0.9);
37+
}
38+
}
39+
}
40+
41+
&-articles-grid {
42+
padding: 1rem;
43+
display: grid;
44+
grid-template-columns: 1fr;
45+
gap: 1.5rem;
46+
47+
@media (min-width: $breakpoint-md) {
48+
grid-template-columns: repeat(2, 1fr);
49+
}
50+
51+
@media (min-width: $breakpoint-lg) {
52+
grid-template-columns: repeat(3, 1fr);
53+
}
54+
}
55+
}
756
}
857

958
.banner__container {
@@ -40,10 +89,6 @@
4089
}
4190

4291
@media (min-width: $breakpoint-md) {
43-
.blog__container {
44-
padding: 0 45px;
45-
}
46-
4792
.banner__container {
4893
h3 {
4994
line-height: 50px;
@@ -56,15 +101,12 @@
56101
}
57102

58103
@media (min-width: $breakpoint-lg) {
59-
60104
.banner__container {
61105
h3 {
62106
display: flex;
63107
align-items: center;
64-
span {
65-
h3 {
66-
padding: 15px;
67-
}
108+
span h3 {
109+
padding: 15px;
68110
}
69111
}
70112
}

0 commit comments

Comments
 (0)