├── .gitignore ├── README.md ├── jsconfig.json ├── next.config.js ├── package-lock.json ├── package.json ├── public ├── data │ └── projects.json ├── favicon.ico ├── img │ ├── icons │ │ ├── icon-144.png │ │ ├── icon-192.png │ │ ├── icon-32.png │ │ ├── icon-48.png │ │ └── icon-96.png │ ├── logo-white.png │ ├── logo.png │ └── placeholders │ │ ├── apps.jpg │ │ ├── banner-devices.png │ │ ├── cursos.jpg │ │ ├── design.jpg │ │ ├── develop.jpg │ │ └── me.jpg ├── manifest.json └── sitemap.xml └── src ├── api └── index.js ├── components ├── Layout.jsx ├── cards │ └── Project.jsx ├── footer │ └── index.jsx ├── header │ └── index.jsx └── popover │ └── index.jsx ├── helpers └── ga.js ├── pages ├── 404.jsx ├── _app.jsx ├── _document.jsx ├── index.jsx ├── politicas.jsx └── portafolio.jsx └── sass ├── components ├── alerts │ └── _popover.scss ├── buttons │ └── _buttons.scss ├── footer │ └── _footer.scss ├── header │ └── _header.scss └── inputs │ └── _inputs.scss ├── core ├── _colors.scss ├── _dev.scss ├── _fonts.scss ├── _spacings.scss └── _trejocode.scss ├── libs ├── _animate.scss ├── _cogotoast.scss └── _nprogress.scss ├── pages ├── _error.scss ├── _home.scss └── _portafolio.scss └── style.scss /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | /public/sw.js 15 | /public/sw.js.map 16 | /public/workbox-*.js 17 | /public/workbox-*.js.map 18 | 19 | # production 20 | /build 21 | 22 | # misc 23 | .DS_Store 24 | *.pem 25 | .env* 26 | 27 | # debug 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | 32 | # local env files 33 | .env.local 34 | .env.development.local 35 | .env.test.local 36 | .env.production.local 37 | 38 | # vercel 39 | .vercel 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Trejocode](https://res.cloudinary.com/trejocode/image/upload/v1586298449/Trejocode/logo_t0otlj.png) 2 | 3 | # 🌐 Trejocode.com - Sitio Web 4 | 5 | Sitio Web oficial de trejocode.com - Construido en Next.js y servido estáticamente 📄 6 | 7 | --- 8 | 9 | Trejocode.com Official Website - Built in Next.js and statically served 10 | 11 | ### 🎉 1.3.0 hCaptcha 12 | 13 | ### 1.2.0 Lazy Loading for Images 14 | 15 | #### 1.1.0 Dark Theme 16 | 17 | 18 | 19 | ### 🏷️ Características / Features 20 | 21 | - Carga de imágenes difereidas / Lazy Load for Images 22 | - Optimizado para SEO / SEO Ready 23 | - Esenciales WCAG 2.1 para la accesibilidad Web / Essential WCAG 2.1 for Web accessibility 24 | - Dark Theme Inicial / Basic Dark Theme 25 | - Ruteador / Router 26 | - Cliente HTTP / HTTP Client 27 | - PWA Listo / PWA Ready 28 | - SASS precargado / SASS incorporated 29 | - NProgress Loader 30 | - Código documentado / Documented code 31 | - Estructura de carpetas / Folder structure 32 | - Última versión mayor de React y Next.js / React and Next.js latest version. 33 | 34 | ### 🚀 Para empezar / Get started 35 | 36 | Estas instrucciones le proporcionarán una copia del proyecto en funcionamiento en su máquina local para fines de desarrollo. Consulte la sección de implementación para obtener notas sobre cómo desplegar el proyecto en producción. 37 | 38 | --- 39 | 40 | These instructions will provide you with a copy of the running project on your local machine for development purposes. See the implementation section for notes on how to deploy the project into production. 41 | 42 | ```bash 43 | cd web 44 | npm install 45 | npm run dev 46 | ``` 47 | 48 | ### 📐 Requisitos / Requirements 49 | 50 | - Node min: 12 51 | - Web Browser 52 | - Text Editor 53 | 54 | ### 📦 Construido con / Build with 55 | 56 | - [Next.js](https://nextjs.org) 57 | - [React Cool Img](https://www.npmjs.com/package/react-cool-img) 58 | 59 | ### 🤝 Colaboradores / Collaborators 60 | 61 | 62 | 63 | 64 | 65 |
Trejito code
Trejocode

🎨 💻 📆
66 | 67 | ## Licencia 68 | 69 | Este proyecto está licenciado bajo la Licencia MIT - vea el archivo [LICENSE.md](LICENSE.md) para más detalles. 70 | 71 | --- 72 | 73 | This project is licensed under the MIT License - see the file [LICENSE.md](LICENSE.md) for more details. 74 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "src" 4 | }, 5 | "include": ["src"] 6 | } -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | exportPathMap: async function ( 3 | defaultPathMap, 4 | { dev, dir, outDir, distDir, buildId } 5 | ) { 6 | return { 7 | "/": { page: "/" }, 8 | "/portafolio": { page: "/portafolio" }, 9 | "/politicas": { page: "/politicas" }, 10 | }; 11 | }, 12 | trailingSlash: false, 13 | }; 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build && next export", 8 | "start": "next start" 9 | }, 10 | "dependencies": { 11 | "@hcaptcha/react-hcaptcha": "^0.3.6", 12 | "axios": "^0.21.1", 13 | "cogo-toast": "^4.2.3", 14 | "next": "10.1.3", 15 | "node-sass": "^5.0.0", 16 | "nprogress": "^0.2.0", 17 | "react": "17.0.2", 18 | "react-cool-img": "^1.2.9", 19 | "react-dom": "17.0.2", 20 | "react-icons": "^4.2.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /public/data/projects.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "title": "Web", 4 | "projects": [ 5 | { 6 | "name": "React Boilerplate", 7 | "slug": "github.com/TrejoCode/react-boilerplate", 8 | "url": "https://github.com/TrejoCode/react-boilerplate", 9 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613481/Trejocode/portfolio/react-boilerplate_e8ciwp.png", 10 | "services": [ 11 | "Open Source", 12 | "Desarrollo Web" 13 | ] 14 | }, 15 | { 16 | "name": "Absolem Marketing", 17 | "slug": "www.absolemarketing.com.mx", 18 | "url": "https://absolemarketing.com.mx", 19 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613479/Trejocode/portfolio/absolem-marketing_yj95cp.png", 20 | "services": [ 21 | "Desarrollo Web", 22 | "Diseño Web" 23 | ] 24 | }, 25 | { 26 | "name": "Buenos Días", 27 | "slug": "www.buenosdiasmexico.mx", 28 | "url": "https://www.buenosdiasmexico.mx", 29 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613482/Trejocode/portfolio/buenos-dias_v2qyqx.png", 30 | "services": [ 31 | "Diseño Web", 32 | "Desarrollo Web" 33 | ] 34 | }, 35 | { 36 | "name": "Best Line Cancún", 37 | "slug": "www.bestlinecancun.com", 38 | "url": "https://www.bestlinecancun.com", 39 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613481/Trejocode/portfolio/bestline-cancun_zrqkzr.png", 40 | "services": [ 41 | "Diseño Web", 42 | "Desarrollo Web" 43 | ] 44 | }, 45 | { 46 | "name": "Core.css", 47 | "slug": "github.com/TrejoCode/css", 48 | "url": "https://github.com/TrejoCode/css", 49 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613482/Trejocode/portfolio/core-css_k8mktc.png", 50 | "services": [ 51 | "Open Source", 52 | "Diseño Web" 53 | ] 54 | }, 55 | { 56 | "name": "CRM Altura", 57 | "slug": "crm.alturacancun.com", 58 | "url": "https://crm.alturacancun.com", 59 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613479/Trejocode/portfolio/altura-cancun_w5qlfz.png", 60 | "services": [ 61 | "Desarrollo Web", 62 | "Desarrollo PWA" 63 | ] 64 | }, 65 | { 66 | "name": "De la Luz", 67 | "slug": "www.delaluz.com.mx", 68 | "url": "https://www.delaluz.com.mx/", 69 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613477/Trejocode/portfolio/delaluz_y6h6oo.png", 70 | "services": [ 71 | "Diseño Web", 72 | "Desarrollo Web" 73 | ] 74 | }, 75 | { 76 | "name": "Elfos Gourmet", 77 | "slug": "www.elfosgourmet.eu", 78 | "url": "https://www.elfosgourmet.eu", 79 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613478/Trejocode/portfolio/elfos-gourmet_f3yx4n.png", 80 | "services": [ 81 | "Diseño Web", 82 | "Desarrollo Web" 83 | ] 84 | }, 85 | { 86 | "name": "BéCé Online", 87 | "slug": "www.beceonline.com", 88 | "url": "https://www.beceonline.com", 89 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613481/Trejocode/portfolio/bece-online_zkamto.png", 90 | "services": [ 91 | "Desarrollo Web", 92 | "Diseño Web" 93 | ] 94 | }, 95 | { 96 | "name": "Chicle y Pega", 97 | "slug": "www.chicleypegacreativo.com", 98 | "url": "https://www.chicleypegacreativo.com", 99 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613482/Trejocode/portfolio/chicle-y-pega_uk9nuv.png", 100 | "services": [ 101 | "Diseño Web", 102 | "Desarrollo Web" 103 | ] 104 | }, 105 | { 106 | "name": "Universidad Politécnica de Quinana Roo", 107 | "slug": "www.upqroo.edu.mx", 108 | "url": "http://www.upqroo.edu.mx", 109 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613479/Trejocode/portfolio/upqroo_u13ntu.png", 110 | "services": [ 111 | "Diseño Web", 112 | "Desarrollo Web" 113 | ] 114 | }, 115 | { 116 | "name": "EM-Sistemas", 117 | "slug": "www.em-sistemas.net", 118 | "url": "https://www.em-sistemas.net/", 119 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613478/Trejocode/portfolio/em-sistemas_aagmbx.png", 120 | "services": [ 121 | "Diseño Web", 122 | "Responsive Web" 123 | ] 124 | }, 125 | { 126 | "name": "California Fitness", 127 | "slug": "www.californiafitness.com.mx", 128 | "url": "http://www.californiafitness.com.mx", 129 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613482/Trejocode/portfolio/california-fitness_smoc04.png", 130 | "services": [ 131 | "Diseño Web", 132 | "Responsive Web" 133 | ] 134 | }, 135 | { 136 | "name": "Go Workers", 137 | "slug": "www.goworkers.es", 138 | "url": "https://www.goworkers.es", 139 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613478/Trejocode/portfolio/go-workers_c3ropc.png", 140 | "services": [ 141 | "Desarrollo Web", 142 | "Desarrollo PWA" 143 | ] 144 | }, 145 | { 146 | "name": "Waala Influencers", 147 | "slug": "www.waalainfluencers.com", 148 | "url": "https://www.waalainfluencers.com", 149 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613480/Trejocode/portfolio/waala_tioy01.png", 150 | "services": [ 151 | "Desarrollo Web", 152 | "Desarrollo PWA" 153 | ] 154 | } 155 | ] 156 | }, 157 | { 158 | "title": "Wordpress", 159 | "projects": [ 160 | { 161 | "name": "Sergio Orduña", 162 | "slug": "www.soarch.mx", 163 | "url": "http://www.soarch.mx", 164 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613479/Trejocode/portfolio/soarch_xq3i8u.png", 165 | "services": [ 166 | "Administración Web", 167 | "Diseño Web" 168 | ] 169 | }, 170 | { 171 | "name": "Eat Copper Branch", 172 | "slug": "www.eatcopperbranch.com", 173 | "url": "https://eatcopperbranch.com", 174 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613478/Trejocode/portfolio/eat-copper-branch_vxgv0s.png", 175 | "services": [ 176 | "Administración Web", 177 | "Diseño Web" 178 | ] 179 | }, 180 | { 181 | "name": "Balcón del zócalo", 182 | "slug": "www.balcondelzocalo.com", 183 | "url": "https://www.balcondelzocalo.com", 184 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613480/Trejocode/portfolio/balcon-del-zocalo_yynxzk.png", 185 | "services": [ 186 | "Administración Web", 187 | "Diseño Web" 188 | ] 189 | }, 190 | { 191 | "name": "Dolcezzza", 192 | "slug": "www.dolcezza.ca", 193 | "url": "https://dolcezza.ca", 194 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613478/Trejocode/portfolio/dolcezza_rzrg0c.png", 195 | "services": [ 196 | "Administración Web", 197 | "Diseño Web" 198 | ] 199 | }, 200 | { 201 | "name": "Luxe Transportation", 202 | "slug": "www.luxe-transportation.com", 203 | "url": "https://luxe-transportation.com/es", 204 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613480/Trejocode/portfolio/luxe-transportation_di8v3u.png", 205 | "services": [ 206 | "Administración Web", 207 | "Diseño Web" 208 | ] 209 | }, 210 | { 211 | "name": "Fidelis Marketing Group", 212 | "slug": "www.fidelismarketinggroup.com", 213 | "url": "https://www.fidelismarketinggroup.com", 214 | "img": "https://res.cloudinary.com/trejocode/image/upload/v1606613479/Trejocode/portfolio/fidelis-marketing_rut7kf.png", 215 | "services": [ 216 | "Administración Web", 217 | "Diseño Web" 218 | ] 219 | } 220 | ] 221 | } 222 | ] -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrejoCode/web/e209f4409a0c314752165a1357573c97fe9bd050/public/favicon.ico -------------------------------------------------------------------------------- /public/img/icons/icon-144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrejoCode/web/e209f4409a0c314752165a1357573c97fe9bd050/public/img/icons/icon-144.png -------------------------------------------------------------------------------- /public/img/icons/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrejoCode/web/e209f4409a0c314752165a1357573c97fe9bd050/public/img/icons/icon-192.png -------------------------------------------------------------------------------- /public/img/icons/icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrejoCode/web/e209f4409a0c314752165a1357573c97fe9bd050/public/img/icons/icon-32.png -------------------------------------------------------------------------------- /public/img/icons/icon-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrejoCode/web/e209f4409a0c314752165a1357573c97fe9bd050/public/img/icons/icon-48.png -------------------------------------------------------------------------------- /public/img/icons/icon-96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrejoCode/web/e209f4409a0c314752165a1357573c97fe9bd050/public/img/icons/icon-96.png -------------------------------------------------------------------------------- /public/img/logo-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrejoCode/web/e209f4409a0c314752165a1357573c97fe9bd050/public/img/logo-white.png -------------------------------------------------------------------------------- /public/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrejoCode/web/e209f4409a0c314752165a1357573c97fe9bd050/public/img/logo.png -------------------------------------------------------------------------------- /public/img/placeholders/apps.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrejoCode/web/e209f4409a0c314752165a1357573c97fe9bd050/public/img/placeholders/apps.jpg -------------------------------------------------------------------------------- /public/img/placeholders/banner-devices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrejoCode/web/e209f4409a0c314752165a1357573c97fe9bd050/public/img/placeholders/banner-devices.png -------------------------------------------------------------------------------- /public/img/placeholders/cursos.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrejoCode/web/e209f4409a0c314752165a1357573c97fe9bd050/public/img/placeholders/cursos.jpg -------------------------------------------------------------------------------- /public/img/placeholders/design.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrejoCode/web/e209f4409a0c314752165a1357573c97fe9bd050/public/img/placeholders/design.jpg -------------------------------------------------------------------------------- /public/img/placeholders/develop.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrejoCode/web/e209f4409a0c314752165a1357573c97fe9bd050/public/img/placeholders/develop.jpg -------------------------------------------------------------------------------- /public/img/placeholders/me.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrejoCode/web/e209f4409a0c314752165a1357573c97fe9bd050/public/img/placeholders/me.jpg -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Trejocode", 3 | "name": "Trejocode", 4 | "icons": [ 5 | { 6 | "src": "img/icons/icon-32.png", 7 | "type": "image/png", 8 | "sizes": "32x32" 9 | }, 10 | { 11 | "src": "/img/icons/icon-48.png", 12 | "type": "image/png", 13 | "sizes": "48x48" 14 | }, 15 | { 16 | "src": "/img/icons/icon-96.png", 17 | "type": "image/png", 18 | "sizes": "96x96" 19 | }, 20 | { 21 | "src": "/img/icons/icon-144.png", 22 | "type": "image/png", 23 | "sizes": "144x144" 24 | }, 25 | { 26 | "src": "/img/icons/icon-192.png", 27 | "type": "image/png", 28 | "sizes": "192x192" 29 | } 30 | ], 31 | "start_url": ".", 32 | "orientation": "portrait", 33 | "lang": "es-MX", 34 | "display": "standalone", 35 | "theme_color": "#33c8a3", 36 | "background_color": "#ffffff" 37 | } 38 | -------------------------------------------------------------------------------- /public/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | https://www.trejocode.com 4 | 1.00 5 | 6 | 7 | https://www.trejocode.com/portafolio 8 | 0.80 9 | 10 | 11 | https://www.trejocode.com/politicas 12 | 0.50 13 | 14 | -------------------------------------------------------------------------------- /src/api/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @version 1.0.0 3 | * @author Trejocode - Sergio 4 | * @description Cliente HTTP para todas las peticiones Web 5 | */ 6 | 7 | import axios from "axios"; 8 | const baseUrl = process.env.NEXT_PUBLIC_API_URL; 9 | 10 | /** 11 | * @description Realizar petición HTTP GET 12 | * @param { String } endpoint: Endpoint de la solicitud 13 | */ 14 | export const get = async (endpoint) => { 15 | try { 16 | const { data } = await axios.get(`${baseUrl}${endpoint}`, { 17 | headers: { 18 | Authorization: process.env.NEXT_PUBLIC_API_KEY, 19 | }, 20 | }); 21 | return { data }; 22 | } catch (error) { 23 | if (error.response) { 24 | return { error: error.response.data }; 25 | } else { 26 | return { error: error.message }; 27 | } 28 | } 29 | }; 30 | 31 | /** 32 | * @description Realizar petición HTTP POST 33 | * @param { String } endpoint: Endpoint de la solicitud 34 | * @param { Object } payload: Objecto body de la solicitud 35 | */ 36 | export const post = async (endpoint, payload) => { 37 | try { 38 | const { data } = await axios.post(`${baseUrl}${endpoint}`, payload, { 39 | headers: { 40 | Authorization: process.env.NEXT_PUBLIC_API_KEY, 41 | }, 42 | }); 43 | return { data }; 44 | } catch (error) { 45 | if (error.response) { 46 | return { error: error.response.data }; 47 | } else { 48 | return { error: error.message }; 49 | } 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /src/components/Layout.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @version 1.0.1 3 | * @author Trejocode - Sergio 4 | * @description Componente 5 | */ 6 | 7 | import Head from "next/head"; 8 | import Header from "components/header"; 9 | import Footer from "components/footer"; 10 | 11 | /** 12 | * @description Plantilla general de la aplicación 13 | * @param { String } title: "meta name" 14 | * @param { String } description: "meta description" 15 | * @param { String } keywords: "meta keywords" 16 | */ 17 | 18 | const Layout = ({ title, description, keywords, children }) => { 19 | return ( 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | {" "} 30 | {title 31 | ? title + " - Trejocode" 32 | : "Trejocode - Diseño y desarrollo Web"}{" "} 33 | 34 | 35 | 36 | 44 | 52 | {/* --- Open Graph --- */} 53 | 54 | 55 | 59 | 67 | 75 | {/* -- IOS Meta -- */} 76 | 77 | 78 | 82 | 86 | {/* --- Fonts --- */} 87 | 91 | {/* --- Twitter --- */} 92 | 93 | 94 | 102 | 106 | 114 | 115 |
116 |
{children}
117 |
118 |
119 | ); 120 | }; 121 | 122 | export default Layout; 123 | -------------------------------------------------------------------------------- /src/components/cards/Project.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @version 1.0.0 3 | * @author Trejocode - Sergio 4 | * @description Componente 5 | */ 6 | 7 | import Img from "react-cool-img"; 8 | 9 | const CardProjects = ({ projects, index = null, limit }) => { 10 | if (index === 0 || index) { 11 | return projects[index].projects.map( 12 | (project, key) => 13 | key < limit && ( 14 |
19 |
20 | {project.name} 21 |
22 |
23 |
24 |
25 | 35 |
36 |
37 | {project.services.map((service, index) => ( 38 |
39 | {service} 40 |
41 | ))} 42 |
43 |
44 |
45 |
46 | ) 47 | ); 48 | } else { 49 | return projects.map((collection, key) => ( 50 |
51 |
52 |

53 | {"{"}{" "} 54 | {collection.title} 55 |

56 |
57 |
58 | {collection.projects.map((project, index) => ( 59 |
64 |
65 | {project.title} 70 |
71 |
72 |
73 |
74 | 84 |
85 |
86 | {project.services.map((service, index) => ( 87 |
88 | {service} 89 |
90 | ))} 91 |
92 |
93 |
94 |
95 | ))} 96 |
97 |
98 | )); 99 | } 100 | }; 101 | 102 | export default CardProjects; 103 | -------------------------------------------------------------------------------- /src/components/footer/index.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @version 1.0.1 3 | * @author Trejocode - Sergio 4 | * @description Componente del Footer 5 | */ 6 | 7 | import { memo } from "react"; 8 | import Link from "next/link"; 9 | import { TiArrowSortedUp } from "react-icons/ti"; 10 | 11 | const Footer = () => ( 12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | 20 | trejocode logo blanco 25 | 26 |
27 |
28 |
29 | 30 | 31 | 32 | 33 | 34 |
35 |
36 |
37 |
38 |
39 |
40 | ); 41 | 42 | export default memo(Footer); 43 | -------------------------------------------------------------------------------- /src/components/header/index.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @version 1.0.1 3 | * @author Trejocode - Sergio 4 | * @description Componente del
5 | */ 6 | 7 | import { useState, useEffect } from "react"; 8 | import Link from "next/link"; 9 | import { FaLightbulb } from "react-icons/fa"; 10 | import { 11 | AiFillLinkedin, 12 | AiFillFacebook, 13 | AiFillYoutube, 14 | AiFillInstagram, 15 | } from "react-icons/ai"; 16 | 17 | const Header = () => { 18 | const [theme, setTheme] = useState("light"); 19 | 20 | /** 21 | * @description Activar DarkTheme o LightTheme 22 | */ 23 | const handleTheme = () => { 24 | if (theme === "light") { 25 | setTheme("dark"); 26 | localStorage.setItem("data-theme", "dark"); 27 | document.documentElement.setAttribute("data-theme", "dark"); 28 | } else { 29 | setTheme("light"); 30 | localStorage.setItem("data-theme", "light"); 31 | document.documentElement.setAttribute("data-theme", "light"); 32 | } 33 | }; 34 | 35 | useEffect(() => { 36 | const theme = localStorage.getItem("data-theme"); 37 | theme 38 | ? document.documentElement.setAttribute("data-theme", theme) 39 | : document.documentElement.setAttribute("data-theme", "light"); 40 | }, []); 41 | 42 | return ( 43 | 151 | ); 152 | }; 153 | 154 | export default Header; 155 | -------------------------------------------------------------------------------- /src/components/popover/index.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @version 1.0.0 3 | * @author Trejocode - Sergio 4 | * @description Componente del 5 | */ 6 | 7 | const Popover = ({ description, link }) => { 8 | return ( 9 |
10 | 15 |
16 | ); 17 | }; 18 | 19 | export default Popover; 20 | -------------------------------------------------------------------------------- /src/helpers/ga.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @version 1.1.0 3 | * @author Sergio - Trejocode 4 | * @description Custom config para GA 5 | */ 6 | 7 | export const GA_TRACKING_ID = process.env.NEXT_PUBLIC_GA_ID; 8 | 9 | /** 10 | * @description Asignar la página actual al visor de GA 11 | * @param { String } url: URL actual 12 | * @url https://developers.google.com/analytics/devguides/collection/gtagjs/pages 13 | */ 14 | export const pageview = (url) => { 15 | window.gtag("config", GA_TRACKING_ID, { 16 | page_path: url, 17 | }); 18 | }; 19 | -------------------------------------------------------------------------------- /src/pages/404.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @version 1.0.0 3 | * @author Trejocode - Sergio 4 | * @description Página de error 404 5 | */ 6 | 7 | import Link from "next/link"; 8 | import Layout from "components/Layout"; 9 | import { FcDeleteDatabase } from "react-icons/fc"; 10 | 11 | const ErrorPage = () => { 12 | return ( 13 | 17 |
18 |
19 | 20 |
21 |

¡Oh no! La página que solicitas no existe

22 |
23 |
24 | 25 | Regresar a inicio 26 | 27 |
28 |
29 |
30 |
31 | ); 32 | }; 33 | 34 | export default ErrorPage; 35 | -------------------------------------------------------------------------------- /src/pages/_app.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @version 1.2.0 3 | * @author Trejocode - Sergio 4 | * @description Custom App para habilitar estilos y NProgress 5 | */ 6 | 7 | import { useEffect } from "react"; 8 | import { useRouter } from "next/router"; 9 | import NProgress from "nprogress"; 10 | import * as ga from "helpers/ga"; 11 | import "sass/style.scss"; 12 | 13 | const App = ({ Component, pageProps }) => { 14 | const router = useRouter(); 15 | 16 | /** 17 | * @description Escuchar los eventos del Router para controlar el Loader y la asignación de la current page para GA 18 | */ 19 | useEffect(() => { 20 | router.events.on("routeChangeStart", () => { 21 | NProgress.start(); 22 | }); 23 | 24 | router.events.on("routeChangeComplete", (url) => { 25 | NProgress.done(); 26 | ga.pageview(url); 27 | }); 28 | 29 | return () => { 30 | router.events.off("routeChangeStart", () => { 31 | NProgress.done(); 32 | }); 33 | }; 34 | }, []); 35 | 36 | return ; 37 | }; 38 | 39 | export default App; 40 | -------------------------------------------------------------------------------- /src/pages/_document.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @version 1.2.0 3 | * @author Trejocode - Sergio 4 | * @description Configuración adicional de la plantilla HTML 5 | */ 6 | 7 | import Document, { Html, Head, Main, NextScript } from "next/document"; 8 | import { GA_TRACKING_ID } from "helpers/ga"; 9 | 10 | class DocumentHTML extends Document { 11 | static async getInitialProps(ctx) { 12 | const initialProps = await Document.getInitialProps(ctx); 13 | return { ...initialProps }; 14 | } 15 | 16 | render() { 17 | return ( 18 | 19 | 20 | 21 |
22 | 23 | 28 | 33 |