├── public └── images │ └── bg.png ├── src ├── app │ ├── favicon.ico │ ├── page.js │ ├── globals.css │ ├── layout.js │ └── projects │ │ └── [projectId] │ │ ├── page.js │ │ └── project.module.css ├── components │ ├── Footer.js │ ├── modals │ │ ├── ParentModal.js │ │ └── modals.module.css │ ├── Hero.js │ ├── SocialIcons.js │ ├── Features.js │ ├── ProjectSwiper.js │ ├── ProjectImage.js │ ├── Header.js │ └── Projects.js ├── constant │ └── home.js └── template.js ├── .husky ├── pre-commit ├── pre-push ├── commit-msg └── _ │ └── husky.sh ├── jsconfig.json ├── next.config.js ├── postcss.config.js ├── .editorconfig ├── cypress ├── fixtures │ └── example.json ├── e2e │ ├── home.cy.js │ └── projectPage.cy.js └── support │ ├── e2e.js │ └── commands.js ├── cypress.config.js ├── .eslintrc.json ├── commitlint.config.js ├── tailwind.config.js ├── package.json ├── CODE_OF_CONDUCT.md ├── README.md └── .gitignore /public/images/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekhadev/openfeedback/HEAD/public/images/bg.png -------------------------------------------------------------------------------- /src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekhadev/openfeedback/HEAD/src/app/favicon.ico -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npm run lint 5 | -------------------------------------------------------------------------------- /.husky/pre-push: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npm run cy:test 5 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "@/*": ["./src/*"] 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {} 3 | 4 | module.exports = nextConfig 5 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx --no-install commitlint --edit "$1" 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | [*] 3 | end_of_line = lf 4 | insert_final_newline = true 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | -------------------------------------------------------------------------------- /cypress/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Using fixtures to represent data", 3 | "email": "hello@cypress.io", 4 | "body": "Fixtures are a great way to mock data for responses to routes" 5 | } 6 | -------------------------------------------------------------------------------- /cypress/e2e/home.cy.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | describe('test home', () => { 3 | it('passes', () => { 4 | cy.visit('http://localhost:3000') 5 | cy.get('h1').should('contain', 'OpenFeedback') 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /cypress.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('cypress') 2 | 3 | module.exports = defineConfig({ 4 | e2e: { 5 | baseUrl: 'http://localhost:3000', 6 | setupNodeEvents(on, config) { 7 | // implement node event listeners here 8 | } 9 | } 10 | }) 11 | -------------------------------------------------------------------------------- /src/app/page.js: -------------------------------------------------------------------------------- 1 | import Features from '@/components/Features' 2 | import Projects from '@/components/Projects' 3 | 4 | export default function Home () { 5 | return ( 6 |
7 | 8 | 9 |
10 | ) 11 | } 12 | -------------------------------------------------------------------------------- /src/components/Footer.js: -------------------------------------------------------------------------------- 1 | import { paragraphFooter, titleLinkFooter } from '@/constant/home' 2 | 3 | const Footer = () => { 4 | return ( 5 | 9 | ) 10 | } 11 | 12 | export default Footer 13 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true, 5 | "node": true 6 | }, 7 | "extends": [ 8 | "standard", 9 | "plugin:react/recommended" 10 | ], 11 | "parserOptions": { 12 | "ecmaVersion": "latest", 13 | "sourceType": "module" 14 | }, 15 | "plugins": [ 16 | "react", 17 | "cypress" 18 | ], 19 | "rules": { 20 | "react/react-in-jsx-scope": "off", 21 | "react/prop-types": "off" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /cypress/e2e/projectPage.cy.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | describe('page projects', () => { 3 | it('passes', () => { 4 | cy.visit('/projects/23') 5 | 6 | cy.get('button').should('contain', 'Ver Demo') 7 | cy.get('button').should('contain', 'Hechale un vistazo al portafolio de') 8 | cy.get('img').should('have.attr', 'alt', 'project image') 9 | 10 | cy.get('img').first().click() 11 | 12 | cy.get('.modal').should('be.visible') 13 | 14 | cy.get('.modal').find('button').click() 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'], 3 | rules: { 4 | 'type-case': [2, 'always', 'lower-case'], 5 | 'type-enum': [2, 'always', [ 6 | 'feat', 7 | 'fix', 8 | 'docs', 9 | 'style', 10 | 'refactor', 11 | 'test', 12 | 'revert', 13 | 'ci' 14 | ]], 15 | 'subject-case': [2, 'always', 'lower-case'], 16 | 'subject-max-length': [2, 'always', 50], 17 | 'subject-min-length': [2, 'always', 10], 18 | 'body-max-length': [2, 'always', 72] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | './src/pages/**/*.{js,ts,jsx,tsx,mdx}', 5 | './src/components/**/*.{js,ts,jsx,tsx,mdx}', 6 | './src/app/**/*.{js,ts,jsx,tsx,mdx}', 7 | ], 8 | theme: { 9 | extend: { 10 | backgroundImage: { 11 | 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', 12 | 'gradient-conic': 13 | 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', 14 | }, 15 | }, 16 | }, 17 | plugins: [], 18 | } 19 | -------------------------------------------------------------------------------- /src/components/modals/ParentModal.js: -------------------------------------------------------------------------------- 1 | import { createPortal } from 'react-dom' 2 | import style from './modals.module.css' 3 | 4 | const Modal = ({ children, close }) => { 5 | return createPortal( 6 |
7 |
8 |
9 |
12 |
13 |
, 14 | window.document.body // El elemento DOM fuera de la jerarquía principal 15 | ) 16 | } 17 | 18 | export default Modal 19 | -------------------------------------------------------------------------------- /src/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | --foreground-rgb: 0, 0, 0; 7 | --background-start-rgb: 214, 219, 220; 8 | --background-end-rgb: 255, 255, 255; 9 | } 10 | 11 | @media (prefers-color-scheme: dark) { 12 | :root { 13 | --foreground-rgb: 255, 255, 255; 14 | --background-start-rgb: 0, 0, 0; 15 | --background-end-rgb: 0, 0, 0; 16 | } 17 | } 18 | 19 | body { 20 | color: rgb(var(--foreground-rgb)); 21 | background: linear-gradient( 22 | to bottom, 23 | transparent, 24 | rgb(var(--background-end-rgb)) 25 | ) 26 | rgb(var(--background-start-rgb)); 27 | } 28 | -------------------------------------------------------------------------------- /cypress/support/e2e.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/e2e.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import './commands' 18 | 19 | // Alternatively you can use CommonJS syntax: 20 | // require('./commands') -------------------------------------------------------------------------------- /src/app/layout.js: -------------------------------------------------------------------------------- 1 | import './globals.css' 2 | import { Inter } from 'next/font/google' 3 | import Header from '@/components/Header' 4 | import Footer from '@/components/Footer' 5 | 6 | const inter = Inter({ subsets: ['latin'] }) 7 | 8 | export const metadata = { 9 | title: 'OpenFeedback', 10 | description: 'Potencia tu carrera como programador en OpenFeedback: Sube tus proyectos y construye un portafolio destacado. Obtén valiosas opiniones de la comunidad y acelera tu crecimiento profesional.' 11 | } 12 | 13 | export default function RootLayout ({ children }) { 14 | return ( 15 | 16 | 17 |
18 | {children} 19 |