├── 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 | You need to enable JavaScript to run this app.
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 )
--------------------------------------------------------------------------------