Refactorizar el codigo, actualizar idiomas, y cambio de colores, Incluir rssService para extraer un rss remoto

This commit is contained in:
Cesar Mendivil 2024-10-15 13:38:34 -07:00
parent 3beaa13073
commit 8c64465d16
15 changed files with 240 additions and 164 deletions

18
src/common/rssService.js Normal file
View File

@ -0,0 +1,18 @@
import axios from 'axios';
import xml2js from 'xml2js';
class RssService {
async getRssFeed(url) {
try {
const response = await axios.get(url);
const result = await xml2js.parseStringPromise(response.data, { mergeAttrs: true });
return result.rss.channel[0].item;
} catch (error) {
console.error('Error fetching RSS feed:', error);
return [];
}
}
}
const rssService = new RssService();
export default rssService;

View File

@ -0,0 +1,8 @@
class TranslationService {
getTranslation(translations, key, currentLanguage) {
return translations.map(t => t[key]?.[currentLanguage] || '').join('');
}
}
const translationService = new TranslationService();
export default translationService;

View File

@ -3,6 +3,7 @@ import { Link } from 'gatsby';
import api from '../../common/api';
import { LanguageContext } from 'context/LanguageContext';
import UrlHelper from '../../common/urlHelper';
import translationService from '../../common/translationService'; // Importa el servicio de traducción
const About = () => {
const { currentLanguage } = useContext(LanguageContext);
@ -22,8 +23,6 @@ const About = () => {
fetchData();
}, [currentLanguage]);
const getTranslation = (translations, key) => translations.map(t => t[key][currentLanguage]).join('');
return (
<section className="about section-padding style-3" data-scroll-index="3">
<div className="top-content">
@ -44,20 +43,20 @@ const About = () => {
<div className="row gx-0 justify-content-end">
<div className="col-lg-5">
<div className="info">
<div className="section-head long-shape mb-40 style-3" dangerouslySetInnerHTML={{ __html: getTranslation(dataAbout.translations, 'about_title1') }}>
<div className="section-head long-shape mb-40 style-3" dangerouslySetInnerHTML={{ __html: translationService.getTranslation(dataAbout.translations, 'about_title1',currentLanguage) }}>
</div>
<h5 className="h5">
{getTranslation(dataAbout.translations, 'about_title2')}
{translationService.getTranslation(dataAbout.translations, 'about_title2',currentLanguage)}
</h5>
<div className="text mb-20">
{getTranslation(dataAbout.translations, 'about_title3')}
{translationService.getTranslation(dataAbout.translations, 'about_title3',currentLanguage)}
</div>
<div className="text mb-70">
{getTranslation(dataAbout.translations, 'about_title4')}
{translationService.getTranslation(dataAbout.translations, 'about_title4',currentLanguage)}
</div>
<Link to={urlHelper.getLocalizedUrl('#')} className="btn rounded-pill bg-blue2 sm-butn text-white">
<span>{getTranslation(dataAbout.translations, 'more_about')}</span>
<span>{translationService.getTranslation(dataAbout.translations, 'more_about',currentLanguage)}</span>
</Link>
</div>
</div>
@ -69,11 +68,11 @@ const About = () => {
<div className="row">
<div className="col-lg-5">
<div className="info pe-lg-5">
<div className="section-head mb-40 style-3" dangerouslySetInnerHTML={{ __html: getTranslation(dataAbout.translations, 'about_title5') }}>
<div className="section-head mb-40 style-3" dangerouslySetInnerHTML={{ __html: translationService.getTranslation(dataAbout.translations, 'about_title5',currentLanguage) }}>
</div>
<div className="text mb-30">
{getTranslation(dataAbout.translations, 'about_title6')}
{translationService.getTranslation(dataAbout.translations, 'about_title6',currentLanguage)}
</div>
<ul>
{
@ -81,7 +80,7 @@ const About = () => {
}
</ul>
<Link to={urlHelper.getLocalizedUrl('#')} className="btn rounded-pill border-blue2 hover-blue2 mt-60 sm-butn">
<span>{getTranslation(dataAbout.translations, 'about_title7')}</span>
<span>{translationService.getTranslation(dataAbout.translations, 'about_title7',currentLanguage)}</span>
</Link>
</div>
</div>

View File

@ -1,6 +1,7 @@
import React, { useEffect, useState, useContext } from 'react';
import api from '../../common/api';
import { LanguageContext } from '../../context/LanguageContext';
import translationService from '../../common/translationService';
const Header = () => {
const { currentLanguage } = useContext(LanguageContext);
const [headers, setHeaders] = useState([]);
@ -16,7 +17,6 @@ const Header = () => {
fetchData();
}, [], [currentLanguage]);
const getTranslation = (headers, key) => headers.map(t => t[key][currentLanguage]).join('');
return (
<header className="style-3 overflow-hidden" data-scroll-index="0">
@ -25,27 +25,27 @@ const Header = () => {
<div className="row">
<div className="col-lg-5">
<div className="info">
<h1 className="h1" dangerouslySetInnerHTML={{ __html: getTranslation(headers, 'header_1') }}></h1>
<h1 className="h1" dangerouslySetInnerHTML={{ __html: translationService.getTranslation(headers, 'header_1',currentLanguage) }}></h1>
<p className="p"></p>
<h5 className="h5">{getTranslation(headers, 'header_2')}<span className="fw-normal ms-1">{getTranslation(headers, 'header_3')}</span></h5>
<h5 className="h5">{translationService.getTranslation(headers, 'header_2',currentLanguage)}<span className="fw-normal ms-1">{translationService.getTranslation(headers, 'header_3',currentLanguage)}</span></h5>
<form action="contact.php" className="form mt-30" method="post">
<div className="row gx-3">
<div className="col-6">
<div className="form-group input-with-icon">
<input type="text" className="form-control" placeholder={getTranslation(headers, 'your_email')} />
<input type="text" className="form-control" placeholder={translationService.getTranslation(headers, 'your_email',currentLanguage)} />
<span className="input-icon"><i className="far fa-envelope"></i></span>
</div>
</div>
<div className="col-6">
<div className="form-group">
<select className="form-select" defaultValue={"Your inquiry about"}>
<option value="">{getTranslation(headers, 'inquiry_about')}</option>
<option value="">{translationService.getTranslation(headers, 'inquiry_about',currentLanguage)}</option>
</select>
</div>
</div>
<div className="col-12">
<button className="btn dark-butn hover-darkBlue rounded-pill w-100 mt-3">
<span>{getTranslation(headers, 'request_a_consultation')}</span>
<span>{translationService.getTranslation(headers, 'request_a_consultation',currentLanguage)}</span>
</button>
</div>
</div>

View File

@ -2,11 +2,11 @@ import React,{ useEffect, useState,useContext } from 'react';
import { Link } from 'gatsby';
import { LanguageContext } from '../../context/LanguageContext';
import api from '../../common/api';
import translationService from '../../common/translationService';
const Pricing = () => {
const { currentLanguage } = useContext(LanguageContext);
const [plansData, setPlansData] = useState({ plans: [], text_traductions: {} });
const [plansData, setPlansData] = useState({ plans: [], text_traductions: [] });
useEffect(() => {
@ -20,7 +20,7 @@ const Pricing = () => {
};
fetchData();
}, []);
}, [],[currentLanguage]);
const { plans, text_traductions } = plansData;
@ -36,16 +36,16 @@ const Pricing = () => {
<div className="col-lg-4">
<div className="info">
<div className="section-head style-3 mb-40">
<h3> {text_traductions.title && text_traductions.title[currentLanguage]} <span> {text_traductions.title2 && text_traductions.title2[currentLanguage]} </span></h3>
<h3> {translationService.getTranslation(text_traductions, 'title',currentLanguage)} <span> {translationService.getTranslation(text_traductions, 'title2',currentLanguage)} </span></h3>
</div>
<small className="text text-gray mb-30">
{text_traductions.subtitle1 && text_traductions.subtitle1[currentLanguage]}
{translationService.getTranslation(text_traductions, 'subtitle1',currentLanguage)}
</small>
<small className="text text-gray d-block">
{text_traductions.subtitle2 && text_traductions.subtitle2[currentLanguage]} <br /> <a href="#" className="color-blue2 text-decoration-underline"> {text_traductions.contact && text_traductions.contact[currentLanguage]}</a> {text_traductions.us_now && text_traductions.us_now[currentLanguage]}
{translationService.getTranslation(text_traductions, 'subtitle2',currentLanguage)} <br /> <a href="#" className="color-blue2 text-decoration-underline"> {translationService.getTranslation(text_traductions, 'contact',currentLanguage)}</a> {translationService.getTranslation(text_traductions, 'us_now',currentLanguage)}
</small>
<Link to="/page-services-5" className="btn rounded-pill border-blue2 hover-blue2 mt-60 sm-butn">
<span>{text_traductions.our_services_button && text_traductions.our_services_button[currentLanguage]}</span>
<span>{translationService.getTranslation(text_traductions, 'our_services_button',currentLanguage)}</span>
</Link>
</div>
</div>
@ -58,12 +58,12 @@ const Pricing = () => {
<div className={`pricing-card ${plan.recommended ? 'dark-card' : ''} style-3 mb-30 mb-lg-0`}>
<div className="card-head">
<div className="title">
<h4>{ plan.title } { plan.recommended && <small>{text_traductions.recommend && text_traductions.recommend[currentLanguage]}</small> }</h4>
<h4>{plan.title} {plan.recommended && <small>{translationService.getTranslation(text_traductions, 'recommended',currentLanguage)}</small>}</h4>
<small>{plan.description}</small>
</div>
<div className="price">
<h5>{plan.price}</h5>
<small>{text_traductions.per_month && text_traductions.per_month[currentLanguage]}</small>
<small>{translationService.getTranslation(text_traductions, 'per_month',currentLanguage)}</small>
</div>
</div>
<div className="card-body">
@ -79,7 +79,7 @@ const Pricing = () => {
</ul>
</div>
<Link to="/page-contact-5" className="btn rounded-pill bg-blue2 sm-butn w-100 text-white">
<span>{text_traductions.get_started_now && text_traductions.get_started_now[currentLanguage]}</span>
<span>{translationService.getTranslation(text_traductions, 'get_started_now',currentLanguage)}</span>
</Link>
</div>
</div>

View File

@ -1,20 +1,37 @@
import React from 'react';
import React, {useEffect, useState, useContext } from 'react';
import { Link } from 'gatsby';
import projects from 'data/Software/projects.json';
import { useIntl } from "gatsby-plugin-intl";
import api from '../../common/api';
import { LanguageContext } from "../../context/LanguageContext";
import translationService from '../../common/translationService'; // Importa el servicio de traducción
const Projects = () => {
const intl = useIntl();
const { currentLanguage } = useContext(LanguageContext);
const [projectsData, setProjectsData] = useState({ projects: [], titles: [] });
useEffect(() => {
const fetchData = async () => {
try {
const response = await api.get('project', 'projects.json');
setProjectsData(response);
} catch (error) {
console.error(error);
}
};
fetchData();
}, [],[currentLanguage]);
return (
<section className="projects section-padding style-3" data-scroll-index="4">
<div className="container">
<div className="section-head style-3 text-center">
<h3>{intl.formatMessage({ id: "our_featured" })} <span>{intl.formatMessage({ id: "projects" })}</span></h3>
<h3>{translationService.getTranslation(projectsData.titles, 'our_featured',currentLanguage)} <span>{translationService.getTranslation(projectsData.titles, 'projects',currentLanguage)}</span></h3>
</div>
<div className="content">
<div className="row">
{
projects.map((project, i) => (
projectsData.projects.map((project, i) => (
<div className={i === 0 ? 'col-lg-7' : i === 1 ? 'col-lg-5' : 'col-lg-6'} key={i}>
<div className="project-card d-block mb-30 style-3">
<Link to={ project.link } className="img img-cover d-block">
@ -31,7 +48,7 @@ const Projects = () => {
</div>
<div className="text-center">
<Link to="http://surteloya.com" className="btn rounded-pill bg-blue2 sm-butn mt-60 text-white">
<span>{intl.formatMessage({ id: "see_all_projects" })}</span>
<span>{translationService.getTranslation(projectsData.titles, 'see_all_projects',currentLanguage)}</span>
</Link>
</div>
</div>

View File

@ -1,25 +1,26 @@
import React , { useEffect, useState }from 'react';
import React , { useEffect, useState,useContext }from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import SwiperCore, { Pagination, Navigation, Autoplay } from 'swiper';
import { useIntl } from "gatsby-plugin-intl";
//import testimonials from 'data/Software/testimonials.json';
import api from '../../common/api';
import { LanguageContext } from 'context/LanguageContext';
import translationService from '../../common/translationService';
import "swiper/css";
import 'swiper/css/autoplay';
import 'swiper/css/navigation';
import 'swiper/css/pagination';
// Importa el servicio de traducción
SwiperCore.use([Pagination, Navigation, Autoplay]);
const Testimonials = () => {
const intl = useIntl();
const [testimonials, setTestimonials] = useState([]);
const { currentLanguage } = useContext(LanguageContext);
const [testimonials, setTestimonials] = useState({testimonials:[],traductions:[]});
useEffect(() => {
const fetchData = async () => {
try {
const response = await api.get('testimonials', 'testimonials.json');
const response = await api.get('testimonial', 'testimonials.json');
setTestimonials(response);
} catch (error) {
console.error(error);
@ -27,13 +28,13 @@ const Testimonials = () => {
};
fetchData();
}, []);
}, [],[currentLanguage]);
return (
<section className="testimonials style-3" data-scroll-index="1">
<div className="container">
<div className="content section-padding">
<div className="section-head style-3">
<h3> {intl.formatMessage({ id: "loved_thousands" })} <span>{intl.formatMessage({ id: "clients" })}</span></h3>
<h3> {translationService.getTranslation(testimonials.traductions, 'loved_thousands',currentLanguage)} <span>{translationService.getTranslation(testimonials.traductions, 'clients',currentLanguage)}</span></h3>
</div>
<div className="testimonial-slider style-3">
<Swiper
@ -74,7 +75,7 @@ const Testimonials = () => {
}}
>
{
testimonials.map((testimonial, index) => (
testimonials.testimonials.map((testimonial, index) => (
<SwiperSlide className="swiper-slide" key={index}>
<div className="testimonial-card style-3">
<div className="text">

View File

@ -59,10 +59,10 @@
left: 0;
height: 50%;
width: 100%;
background: -webkit-gradient(linear, left top, right top, from(#0c3df4), to(#02b5ff));
background: -webkit-linear-gradient(left, #0c3df4 0%, #02b5ff 100%);
background: -o-linear-gradient(left, #0c3df4 0%, #02b5ff 100%);
background: linear-gradient(to right, #0c3df4 0%, #02b5ff 100%);
background: -webkit-gradient(linear, left top, right top, from(#4a00e1), to(#8169f1));
background: -webkit-linear-gradient(left, #4a00e1 0%, #8169f1 100%);
background: -o-linear-gradient(left, #4a00e1 0%, #8169f1 100%);
background: linear-gradient(to right, #4a00e1 0%, #8169f1 100%);
-webkit-transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
-o-transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1); }

View File

@ -314,10 +314,10 @@ small.text {
left: 0;
height: 50%;
width: 100%;
background: -webkit-gradient(linear, left top, right top, from(#0c3df4), to(#02b5ff));
background: -webkit-linear-gradient(left, #0c3df4 0%, #02b5ff 100%);
background: -o-linear-gradient(left, #0c3df4 0%, #02b5ff 100%);
background: linear-gradient(to right, #0c3df4 0%, #02b5ff 100%);
background: -webkit-gradient(linear, left top, right top, from(#4a00e1), to(#8169f1));
background: -webkit-linear-gradient(left, #4a00e1 0%, #8169f1 100%);
background: -o-linear-gradient(left, #4a00e1 0%, #8169f1 100%);
background: linear-gradient(to right, #4a00e1 0%, #8169f1 100%);
-webkit-transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
-o-transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1); }

View File

@ -90,7 +90,7 @@ TABLE OF CONTENTS:-
--color-yellowGreen:#cef54b;
--color-gray:#eef4f8;
--color-gray2:#f0eff5;
--color-main-grad: linear-gradient(to right, #0c3df4 0%, #02b5ff 100%); }
--color-main-grad: linear-gradient(to right, #4a00e1 0%, #8169f1 100%); }
.color-main {
color: var(--color-main) !important; }
@ -665,10 +665,10 @@ small.text {
left: 0;
height: 50%;
width: 100%;
background: -webkit-gradient(linear, left top, right top, from(#0c3df4), to(#02b5ff));
background: -webkit-linear-gradient(left, #0c3df4 0%, #02b5ff 100%);
background: -o-linear-gradient(left, #0c3df4 0%, #02b5ff 100%);
background: linear-gradient(to right, #0c3df4 0%, #02b5ff 100%);
background: -webkit-gradient(linear, left top, right top, from(#4a00e1), to(#8169f1));
background: -webkit-linear-gradient(left, #4a00e1 0%, #8169f1 100%);
background: -o-linear-gradient(left, #4a00e1 0%, #8169f1 100%);
background: linear-gradient(to right, #4a00e1 0%, #8169f1 100%);
-webkit-transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
-o-transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1); }
@ -1426,10 +1426,10 @@ small.text {
width: 150%;
height: 100%;
z-index: 1;
background: -webkit-gradient(linear, left top, right top, color-stop(10%, #0c3df4), color-stop(45%, #02b5ff), color-stop(#02b5ff), to(#0c3df4));
background: -webkit-linear-gradient(left, #0c3df4 10%, #02b5ff 45%, #02b5ff, #0c3df4);
background: -o-linear-gradient(left, #0c3df4 10%, #02b5ff 45%, #02b5ff, #0c3df4);
background: linear-gradient(to right, #0c3df4 10%, #02b5ff 45%, #02b5ff, #0c3df4);
background: -webkit-gradient(linear, left top, right top, color-stop(10%, #4a00e1), color-stop(45%, #8169f1), color-stop(#8169f1), to(#4a00e1));
background: -webkit-linear-gradient(left, #4a00e1 10%, #8169f1 45%, #8169f1, #4a00e1);
background: -o-linear-gradient(left, #4a00e1 10%, #8169f1 45%, #8169f1, #4a00e1);
background: linear-gradient(to right, #4a00e1 10%, #8169f1 45%, #8169f1, #4a00e1);
-webkit-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
transition: all 0.3s ease; }

View File

@ -18,7 +18,7 @@
}
.cls-3 {
fill: #0c3df4;
fill: #4a00e1;
fill-rule: evenodd;
filter: url(#filter);
}

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -5,11 +5,7 @@
"title": "Standard",
"description": "Basic features",
"price": "$29",
"features": [
"3 Projects",
"6 Months Support & SEO",
"Basic Dashboard"
]
"features": ["3 Projects", "6 Months Support & SEO", "Basic Dashboard"]
},
{
"title": "Pro",
@ -25,7 +21,8 @@
]
}
],
"text_traductions":{
"text_traductions": [
{
"our_services_button": {
"es": "Nuestros Servicios",
"en": "Our Services"
@ -67,5 +64,7 @@
"en": "Get Started Now"
}
}
]
}
}

View File

@ -1,4 +1,6 @@
[
{
"project": {
"projects": [
{
"image": "/assets/img/projects/3.png",
"title": "Catty Boxes NFT Blockchain",
@ -23,4 +25,22 @@
"description": "Game Development",
"link": "http://surteloya.com"
}
],
"titles": [
{
"our_featured": {
"es": "nuestros destacados",
"en": "our featured"
},
"projects": {
"es": "proyectos",
"en": "projects"
},
"see_all_projects":{
"es": "ver todos los proyectos",
"en": "see all projects"
}
}
]
}
}

View File

@ -1,4 +1,5 @@
{
"testimonial": {
"testimonials": [
{
"text": "“We encountered a problem with processing big data and after only 1 week, all fixed, professional, fast & affordable price!”",
@ -24,5 +25,18 @@
"author": "Cesar Mendivil",
"positon": "Product Management at Invisionapp"
}
],
"traductions": [
{
"clients":{
"es":"Clientes",
"en":"Clients"
},
"loved_thousands":{
"es":"Amado por muchos",
"en":"Loved by thousands"
}
}
]
}
}

View File

@ -69,10 +69,10 @@ h5, h6 {
top: 0;
width: 100%;
height: 2px;
background: -webkit-gradient(linear, left top, right top, color-stop(10%, #0c3df4), color-stop(45%, #02b5ff));
background: -webkit-linear-gradient(left, #0c3df4 10%, #02b5ff 45%);
background: -o-linear-gradient(left, #0c3df4 10%, #02b5ff 45%);
background: linear-gradient(to right, #0c3df4 10%, #02b5ff 45%); }
background: -webkit-gradient(linear, left top, right top, color-stop(10%, #4a00e1), color-stop(45%, #8169f1));
background: -webkit-linear-gradient(left, #4a00e1 10%, #8169f1 45%);
background: -o-linear-gradient(left, #4a00e1 10%, #8169f1 45%);
background: linear-gradient(to right, #4a00e1 10%, #8169f1 45%); }
.nav-preview .dropDown .dropDownMenu .dropdown-items {
position: relative;
text-transform: capitalize;