├── public ├── robots.txt ├── manifest.json └── index.html ├── .babelrc ├── src ├── redux │ ├── store.js │ └── greetings │ │ └── greetings.js ├── setupTests.js ├── App.js ├── index.js ├── reportWebVitals.js ├── index.css └── components │ └── Greetings.js ├── .gitignore ├── .stylelintrc.json ├── .eslintrc.json ├── LICENSE ├── package.json ├── .github └── workflows │ └── linters.yml └── README.md /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-react" 4 | ], 5 | "plugins": ["@babel/plugin-syntax-jsx"] 6 | } -------------------------------------------------------------------------------- /src/redux/store.js: -------------------------------------------------------------------------------- 1 | import { configureStore } from '@reduxjs/toolkit'; 2 | import rootReducer from './greetings/greetings'; 3 | 4 | export default configureStore({ 5 | reducer: { 6 | root: rootReducer, 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "theme_color": "#000000", 7 | "background_color": "#ffffff" 8 | } 9 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Routes, Route, BrowserRouter as Router } from 'react-router-dom'; 3 | import Greetings from './components/Greetings'; 4 | 5 | function App() { 6 | return ( 7 | 8 | 9 | } /> 10 | 11 | 12 | ); 13 | } 14 | 15 | export default App; 16 | -------------------------------------------------------------------------------- /.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 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import { Provider } from 'react-redux'; 4 | import App from './App'; 5 | import store from './redux/store'; 6 | import './index.css'; 7 | 8 | const root = ReactDOM.createRoot(document.getElementById('root')); 9 | root.render( 10 | 11 | 12 | 13 | 14 | , 15 | ); 16 | -------------------------------------------------------------------------------- /src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = (onPerfEntry) => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ 4 | getCLS, getFID, getFCP, getLCP, getTTFB, 5 | }) => { 6 | getCLS(onPerfEntry); 7 | getFID(onPerfEntry); 8 | getFCP(onPerfEntry); 9 | getLCP(onPerfEntry); 10 | getTTFB(onPerfEntry); 11 | }); 12 | } 13 | }; 14 | 15 | export default reportWebVitals; 16 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | /* Style the h1 heading */ 2 | h1 { 3 | text-align: center; 4 | font-family: sans-serif; 5 | font-size: 48px; 6 | font-weight: bold; 7 | position: relative; 8 | top: 50%; 9 | transform: translateY(-50%); 10 | color: #54c5f9; 11 | text-shadow: 0 2px 5px rgba(0, 0, 0, 0.3); 12 | } 13 | 14 | .greeting-container { 15 | background-color: #fff; 16 | border-radius: 10px; 17 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); 18 | padding: 50px; 19 | text-align: center; 20 | background-image: linear-gradient(to bottom, #fff, #f2f2f2); 21 | } 22 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["stylelint-config-standard"], 3 | "plugins": ["stylelint-scss", "stylelint-csstree-validator"], 4 | "rules": { 5 | "at-rule-no-unknown": [ 6 | true, 7 | { 8 | "ignoreAtRules": ["tailwind", "apply", "variants", "responsive", "screen"] 9 | } 10 | ], 11 | "scss/at-rule-no-unknown": [ 12 | true, 13 | { 14 | "ignoreAtRules": ["tailwind", "apply", "variants", "responsive", "screen"] 15 | } 16 | ], 17 | "csstree/validator": true 18 | }, 19 | "ignoreFiles": ["build/**", "dist/**", "**/reset*.css", "**/bootstrap*.css", "**/*.js", "**/*.jsx"] 20 | } -------------------------------------------------------------------------------- /src/redux/greetings/greetings.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | 3 | const greetingReducer = (state = null, action) => { 4 | switch (action.type) { 5 | case 'GET_GREETING': 6 | return action.payload; 7 | default: 8 | return state; 9 | } 10 | }; 11 | 12 | export const fetchgreeting = () => async (dispatch) => { 13 | await fetch('http://127.0.0.1:3000/api/greetings') 14 | .then((response) => response.json()) 15 | .then((data) => { 16 | dispatch({ type: 'GET_GREETING', payload: data }); 17 | }); 18 | }; 19 | 20 | const rootReducer = combineReducers({ 21 | greeting: greetingReducer, 22 | }); 23 | 24 | export default rootReducer; 25 | -------------------------------------------------------------------------------- /src/components/Greetings.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import { useDispatch, useSelector } from 'react-redux'; 3 | import { fetchgreeting } from '../redux/greetings/greetings'; 4 | 5 | const Greetings = () => { 6 | const dispatch = useDispatch(); 7 | const messages = useSelector((state) => state.root.greeting); 8 | 9 | useEffect(() => { 10 | dispatch(fetchgreeting()); 11 | }, []); 12 | 13 | if (!messages) { 14 | return
Loading...
; 15 | } 16 | 17 | return ( 18 | <> 19 |
20 |

{messages.message}

21 |
22 | 23 | ); 24 | }; 25 | 26 | export default Greetings; 27 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true, 5 | "jest": true 6 | }, 7 | "parser": "@babel/eslint-parser", 8 | "parserOptions": { 9 | "ecmaFeatures": { 10 | "jsx": true 11 | }, 12 | "ecmaVersion": 2018, 13 | "sourceType": "module" 14 | }, 15 | "extends": ["airbnb", "plugin:react/recommended", "plugin:react-hooks/recommended"], 16 | "plugins": ["react"], 17 | "rules": { 18 | "react/jsx-filename-extension": ["warn", { "extensions": [".js", ".jsx"] }], 19 | "react/react-in-jsx-scope": "off", 20 | "import/no-unresolved": "off", 21 | "no-shadow": "off" 22 | }, 23 | "overrides": [ 24 | { 25 | // feel free to replace with your preferred file pattern - eg. 'src/**/*Slice.js' or 'redux/**/*Slice.js' 26 | "files": ["src/**/*Slice.js"], 27 | // avoid state param assignment 28 | "rules": { "no-param-reassign": ["error", { "props": false }] } 29 | } 30 | ], 31 | "ignorePatterns": [ 32 | "dist/", 33 | "build/" 34 | ] 35 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Ahmed Eid 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hello-react-front-end", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@reduxjs/toolkit": "^1.9.7", 7 | "@testing-library/jest-dom": "^5.17.0", 8 | "@testing-library/react": "^13.4.0", 9 | "@testing-library/user-event": "^13.5.0", 10 | "react": "^18.2.0", 11 | "react-dom": "^18.2.0", 12 | "react-redux": "^8.1.3", 13 | "react-router-dom": "^6.18.0", 14 | "react-scripts": "5.0.1", 15 | "redux": "^4.2.1", 16 | "redux-thunk": "^2.4.2", 17 | "web-vitals": "^2.1.4" 18 | }, 19 | "scripts": { 20 | "start": "react-scripts start", 21 | "build": "react-scripts build", 22 | "test": "react-scripts test", 23 | "eject": "react-scripts eject" 24 | }, 25 | "eslintConfig": { 26 | "extends": [ 27 | "react-app", 28 | "react-app/jest" 29 | ] 30 | }, 31 | "browserslist": { 32 | "production": [ 33 | ">0.2%", 34 | "not dead", 35 | "not op_mini all" 36 | ], 37 | "development": [ 38 | "last 1 chrome version", 39 | "last 1 firefox version", 40 | "last 1 safari version" 41 | ] 42 | }, 43 | "devDependencies": { 44 | "@babel/core": "^7.23.3", 45 | "@babel/eslint-parser": "^7.23.3", 46 | "@babel/plugin-syntax-jsx": "^7.23.3", 47 | "@babel/preset-react": "^7.23.3", 48 | "eslint": "^7.32.0", 49 | "eslint-config-airbnb": "^18.2.1", 50 | "eslint-plugin-import": "^2.29.0", 51 | "eslint-plugin-jsx-a11y": "^6.8.0", 52 | "eslint-plugin-react": "^7.33.2", 53 | "eslint-plugin-react-hooks": "^4.6.0", 54 | "stylelint": "^13.13.1", 55 | "stylelint-config-standard": "^21.0.0", 56 | "stylelint-csstree-validator": "^1.9.0", 57 | "stylelint-scss": "^3.21.0" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 16 | 17 | 26 | React App 27 | 28 | 29 | 30 |
31 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /.github/workflows/linters.yml: -------------------------------------------------------------------------------- 1 | name: Linters 2 | 3 | on: pull_request 4 | 5 | env: 6 | FORCE_COLOR: 1 7 | 8 | jobs: 9 | eslint: 10 | name: ESLint 11 | runs-on: ubuntu-22.04 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: actions/setup-node@v3 15 | with: 16 | node-version: "18.x" 17 | - name: Setup ESLint 18 | run: | 19 | npm install --save-dev eslint@7.x eslint-config-airbnb@18.x eslint-plugin-import@2.x eslint-plugin-jsx-a11y@6.x eslint-plugin-react@7.x eslint-plugin-react-hooks@4.x @babel/eslint-parser@7.x @babel/core@7.x @babel/plugin-syntax-jsx@7.x @babel/preset-env@7.x @babel/preset-react@7.x 20 | [ -f .eslintrc.json ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/react-redux/.eslintrc.json 21 | [ -f .babelrc ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/react-redux/.babelrc 22 | - name: ESLint Report 23 | run: npx eslint "**/*.{js,jsx}" 24 | stylelint: 25 | name: Stylelint 26 | runs-on: ubuntu-22.04 27 | steps: 28 | - uses: actions/checkout@v3 29 | - uses: actions/setup-node@v3 30 | with: 31 | node-version: "18.x" 32 | - name: Setup Stylelint 33 | run: | 34 | npm install --save-dev stylelint@13.x stylelint-scss@3.x stylelint-config-standard@21.x stylelint-csstree-validator@1.x 35 | [ -f .stylelintrc.json ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/react-redux/.stylelintrc.json 36 | - name: Stylelint Report 37 | run: npx stylelint "**/*.{css,scss}" 38 | nodechecker: 39 | name: node_modules checker 40 | runs-on: ubuntu-22.04 41 | steps: 42 | - uses: actions/checkout@v3 43 | - name: Check node_modules existence 44 | run: | 45 | if [ -d "node_modules/" ]; then echo -e "\e[1;31mThe node_modules/ folder was pushed to the repo. Please remove it from the GitHub repository and try again."; echo -e "\e[1;32mYou can set up a .gitignore file with this folder included on it to prevent this from happening in the future." && exit 1; fi -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |

hello_rails_front_end

4 | 5 | 6 | 7 | # 📗 Table of Contents 8 | 9 | - [📗 Table of Contents](#-table-of-contents) 10 | - [📖 hello\_rails\_front\_end ](#-hello_rails_front_end-) 11 | - [💻 link to back end ](#-link-to-back-end-) 12 | - [🛠 Built With ](#-built-with-) 13 | - [Tech Stack ](#tech-stack-) 14 | - [Key Features ](#key-features-) 15 | - [💻 Getting Started ](#-getting-started-) 16 | - [Prerequisites](#prerequisites) 17 | - [Setup](#setup) 18 | - [Install](#install) 19 | - [Usage](#usage) 20 | - [👥 Author ](#-author-) 21 | - [🔭 Future Features ](#-future-features-) 22 | - [🤝 Contributing ](#-contributing-) 23 | - [⭐️ Show your support ](#️-show-your-support-) 24 | - [🙏 Acknowledgments ](#-acknowledgments-) 25 | - [📝 License ](#-license-) 26 | 27 | 28 | 29 | # 📖 hello_rails_front_end 30 | 31 | **hello_rails_front_end** Introducing 'hello-react-front-end,' a straightforward React-Redux application. It employs a primary App component with react-router for seamless navigation. A designated route directs users to the Greeting component, showcasing dynamic greeting messages retrieved from an external API. The application leverages Redux for efficient state management, focusing on handling API requests and dynamically updating the displayed greeting message. 32 | 33 | ## 💻 link to back end 34 | 35 | 36 | [Link to Back End](https://github.com/ahmedeid6842/hello-rails-back-end) 37 | 38 |

(back to top)

39 | 40 | 41 | ## 🛠 Built With 42 | 43 | ### Tech Stack 44 | 45 |
46 | Technologies 47 | 51 |
52 |
53 | Linters 54 | 57 |
58 | 59 | 60 | ### Key Features 61 | 62 | - [x] **Integration of Ruby on Rails and React** 63 | - [x] **API Endpoint for Generating Random Greetings** 64 | - [x] **Navigation Using React Router** 65 | - [x] **State Management with Redux** 66 | - [x] **Setting the Static View as the Root** 67 | 68 | 69 |

(back to top)

70 | 71 | 72 | ## 💻 Getting Started 73 | 74 | To get a local copy up and running, follow these steps. 75 | 76 | ### Prerequisites 77 | 78 | Before you begin, make sure you have the following prerequisites installed on your system: 79 | 80 | - Ruby: You need Ruby to run the Ruby on Rails application. 81 | - Bundler: Bundler is used to manage gem dependencies in your Ruby project. 82 | 83 | ### Setup 84 | 85 | Clone this repository to your desired folder: 86 | 87 | sh
88 | cd my-folder
89 | git clone https://github.com/ahmedeid6842/hello-react-front-end 90 | 91 | ### Install 92 | 93 | Install this project with: 94 | 95 | - npm install 96 | - npm start 97 | 98 | ### Usage 99 | 100 | To run the project, execute the following command: 101 | 102 | rails server 103 | 104 | **Ahmed Eid 🙋‍♂️** 105 | - Github: [@ahmedeid6842](https://github.com/ahmedeid6842/) 106 | - LinkedIn : [Ahmed Eid](https://www.linkedin.com/in/ahmed-eid-0018571b1/) 107 | - Twitter: [@ahmedeid2684](https://twitter.com/ahmedeid2684) 108 | 109 |

(back to top)

110 | 111 | 112 | ## 🔭 Future Features 113 | 114 | - [ ] **Personalized Greetings** 115 | 116 | 117 |

(back to top)

118 | 119 | ## 🤝 Contributing 120 | 121 | Contributions, issues, and feature requests are welcome! 122 | 123 | Feel free to check the [issues page](https://github.com/ahmedeid6842/hello-react-front-end/issues). 124 | 125 |

(back to top)

126 | 127 | ## ⭐️ Show your support 128 | 129 | If you like this project please feel free to send me corrections for make it better I would feel glad to read your comments. 130 | And think If you enjoy gift me a star. 131 | 132 |

(back to top)

133 | 134 | ## 🙏 Acknowledgments 135 | 136 | - Microverse for providing the opportunity to learn Git and GitHub in a collaborative environment. 137 | 138 |

(back to top)

139 | 140 | 141 | ## 📝 License 142 | 143 | This project is licensed under the MIT License - you can click here to have more details [MIT](./LICENSE) licensed. 144 | 145 |

(back to top)

--------------------------------------------------------------------------------