├── public
├── robots.txt
├── favicon.ico
├── logo192.png
├── logo512.png
├── manifest.json
└── index.html
├── .babelrc
├── src
├── App.css
├── App.js
├── externalFunction.js
├── redux
│ ├── configureStore.js
│ ├── imf
│ │ ├── __mocks__
│ │ │ └── imf.js
│ │ └── imf.js
│ └── individual
│ │ ├── __mocks__
│ │ └── individual.js
│ │ └── individual.js
├── index.js
├── components
│ ├── Header.js
│ ├── Router.js
│ ├── DetailsPage.js
│ ├── CallAPI.js
│ ├── HomePage.js
│ └── style.css
└── tests
│ ├── imf.test.js
│ └── individual.test.js
├── .gitignore
├── .stylelintrc.json
├── .eslintrc.json
├── netlify.toml
├── MIT.md
├── package.json
├── README.md
└── .github
└── workflows
└── linters.yml
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pratap-panabaka/metrics-webapp-mutual-funds/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pratap-panabaka/metrics-webapp-mutual-funds/HEAD/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pratap-panabaka/metrics-webapp-mutual-funds/HEAD/public/logo512.png
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "@babel/preset-react"
4 | ],
5 | "plugins": ["@babel/plugin-syntax-jsx"]
6 | }
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | @import url('https://use.typekit.net/gmu8egi.css');
2 |
3 | html,
4 | body {
5 | font-family: 'Lato', sans-serif;
6 | }
7 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import Router from './components/Router';
2 | import './App.css';
3 |
4 | function App() {
5 | return (
6 | <>
7 |
8 | >
9 | );
10 | }
11 |
12 | export default App;
13 |
--------------------------------------------------------------------------------
/src/externalFunction.js:
--------------------------------------------------------------------------------
1 | const getMultipleRandom = (arr, num) => {
2 | const shuffled = [...arr].sort(() => 0.5 - Math.random());
3 |
4 | return shuffled.slice(0, num);
5 | };
6 |
7 | export default getMultipleRandom;
8 |
--------------------------------------------------------------------------------
/src/redux/configureStore.js:
--------------------------------------------------------------------------------
1 | import { configureStore, combineReducers } from '@reduxjs/toolkit';
2 | import imfReducer from './imf/imf';
3 | import getIndividualDataReducer from './individual/individual';
4 |
5 | const reducer = combineReducers({ imfReducer, getIndividualDataReducer });
6 |
7 | const store = configureStore({ reducer });
8 |
9 | export default store;
10 |
--------------------------------------------------------------------------------
/.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 |
25 | # Local Netlify folder
26 | .netlify
27 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import { BrowserRouter } from 'react-router-dom';
4 | import { Provider } from 'react-redux';
5 | import App from './App';
6 | import store from './redux/configureStore';
7 |
8 | const root = ReactDOM.createRoot(document.getElementById('root'));
9 | root.render(
10 |
11 |
12 |
13 |
14 | ,
15 | );
16 |
--------------------------------------------------------------------------------
/src/redux/imf/__mocks__/imf.js:
--------------------------------------------------------------------------------
1 | const fetchedObj = [{ schemeCode: 100027, schemeName: 'Grindlays Super Saver Income Fund-GSSIF-Half Yearly Dividend' },
2 | { schemeCode: 100028, schemeName: 'Grindlays Super Saver Income Fund-GSSIF-Quaterly Dividend' },
3 | { schemeCode: 100029, schemeName: 'Grindlays Super Saver Income Fund-GSSIF-Growth' },
4 | { schemeCode: 100030, schemeName: 'Grindlays Super Saver Income Fund-GSSIF-Annual Dividend' }];
5 |
6 | const getDataAction = () => () => fetchedObj;
7 |
8 | export default getDataAction;
9 |
--------------------------------------------------------------------------------
/src/components/Header.js:
--------------------------------------------------------------------------------
1 | import { FaMicrophone } from 'react-icons/fa';
2 | import { FiSettings } from 'react-icons/fi';
3 | import './style.css';
4 |
5 | const Header = () => (
6 | <>
7 |
8 |
9 |
10 | Indian Mutual Funds
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | >
19 | );
20 |
21 | export default Header;
22 |
--------------------------------------------------------------------------------
/src/redux/individual/__mocks__/individual.js:
--------------------------------------------------------------------------------
1 | const fetchedObj = {
2 | meta:
3 | {
4 | fund_house: 'DSP Mutual Fund',
5 | scheme_type: 'Open Ended Schemes',
6 | scheme_category: 'Debt Scheme - Gilt Fund',
7 | scheme_code: 100086,
8 | scheme_name: 'DSP Government Securities Fund - Regular Plan - IDCW - Monthly',
9 | },
10 | data: [{ date: '03-10-2022', nav: '10.70250' }, { date: '30-09-2022', nav: '10.71460' }],
11 | status: 'SUCCESS',
12 | };
13 |
14 | const getIndividualDataAction = () => () => fetchedObj;
15 |
16 | export default getIndividualDataAction;
17 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/src/redux/imf/imf.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | const GET_DATA = 'GET_DATA';
4 | const API = 'https://api.mfapi.in/mf';
5 |
6 | const initialState = [];
7 |
8 | const imfReducer = (state = initialState, action) => {
9 | switch (action.type) {
10 | case GET_DATA:
11 | return action.payload;
12 | default:
13 | return state;
14 | }
15 | };
16 |
17 | export const getDataAction = () => (dispatch) => {
18 | axios.get(API).then((response) => {
19 | const { data } = response;
20 | dispatch({ type: GET_DATA, payload: data });
21 | });
22 | };
23 |
24 | export default imfReducer;
25 |
--------------------------------------------------------------------------------
/.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 | }
21 |
--------------------------------------------------------------------------------
/.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 | "ignorePatterns": [
24 | "dist/",
25 | "build/"
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/src/components/Router.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { Routes, Route } from 'react-router-dom';
3 | import HomePage from './HomePage';
4 | import CallAPI from './CallAPI';
5 | import DetailsPage from './DetailsPage';
6 |
7 | const Router = () => {
8 | const [id, setId] = useState('');
9 |
10 | const handleId = (e) => {
11 | setId(e.target.parentElement.id);
12 | };
13 |
14 | return (
15 | <>
16 |
17 | } />
18 | } />
19 | } />
20 |
21 | >
22 | );
23 | };
24 |
25 | export default Router;
26 |
--------------------------------------------------------------------------------
/src/redux/individual/individual.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | const GET_INDIVIDUAL_DATA = 'GET_INDIVIDUAL_DATA';
4 | const API = 'https://api.mfapi.in/mf';
5 |
6 | const initialState = {
7 | meta: {},
8 | data: [],
9 | status: '',
10 | };
11 |
12 | const getIndividualDataReducer = (state = initialState, action) => {
13 | switch (action.type) {
14 | case GET_INDIVIDUAL_DATA:
15 | return action.payload;
16 | default:
17 | return state;
18 | }
19 | };
20 |
21 | export const getIndividualDataAction = (id) => (dispatch) => {
22 | axios.get(`${API}/${id}`).then((response) => {
23 | const { data } = response;
24 | dispatch({ type: GET_INDIVIDUAL_DATA, payload: data });
25 | });
26 | };
27 |
28 | export default getIndividualDataReducer;
29 |
--------------------------------------------------------------------------------
/src/tests/imf.test.js:
--------------------------------------------------------------------------------
1 | import imfReducer, { getDataAction } from '../redux/imf/imf';
2 |
3 | jest.mock('../redux/imf/imf');
4 |
5 | const toCompare = [{ schemeCode: 100027, schemeName: 'Grindlays Super Saver Income Fund-GSSIF-Half Yearly Dividend' },
6 | { schemeCode: 100028, schemeName: 'Grindlays Super Saver Income Fund-GSSIF-Quaterly Dividend' },
7 | { schemeCode: 100029, schemeName: 'Grindlays Super Saver Income Fund-GSSIF-Growth' },
8 | { schemeCode: 100030, schemeName: 'Grindlays Super Saver Income Fund-GSSIF-Annual Dividend' }];
9 |
10 | describe('Test Store', () => {
11 | test('test imfReducer', () => {
12 | const initialState = [];
13 | const fetchedState = imfReducer(initialState, getDataAction);
14 | expect(fetchedState()).toStrictEqual(toCompare);
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | # example netlify.toml
2 | [build]
3 | command = "react-scripts build"
4 | functions = "netlify/functions"
5 | publish = "build"
6 |
7 | ## Uncomment to use this redirect for Single Page Applications like create-react-app.
8 | ## Not needed for static site generators.
9 | #[[redirects]]
10 | # from = "/*"
11 | # to = "/index.html"
12 | # status = 200
13 |
14 | ## (optional) Settings for Netlify Dev
15 | ## https://github.com/netlify/cli/blob/main/docs/netlify-dev.md#project-detection
16 | #[dev]
17 | # command = "yarn start" # Command to start your dev server
18 | # port = 3000 # Port that the dev server will be listening on
19 | # publish = "dist" # Folder with the static content for _redirect file
20 |
21 | ## more info on configuring this file: https://docs.netlify.com/configure-builds/file-based-configuration/
22 |
--------------------------------------------------------------------------------
/src/tests/individual.test.js:
--------------------------------------------------------------------------------
1 | import getIndividualDataReducer, { getIndividualDataAction } from '../redux/individual/individual';
2 |
3 | jest.mock('../redux/individual/individual');
4 |
5 | const toCompare = {
6 | meta:
7 | {
8 | fund_house: 'DSP Mutual Fund',
9 | scheme_type: 'Open Ended Schemes',
10 | scheme_category: 'Debt Scheme - Gilt Fund',
11 | scheme_code: 100086,
12 | scheme_name: 'DSP Government Securities Fund - Regular Plan - IDCW - Monthly',
13 | },
14 | data: [{ date: '03-10-2022', nav: '10.70250' }, { date: '30-09-2022', nav: '10.71460' }],
15 | status: 'SUCCESS',
16 | };
17 |
18 | describe('Test Store', () => {
19 | test('test getIndividualDataReducer', () => {
20 | const initialState = [];
21 | const fetchedState = getIndividualDataReducer(initialState, getIndividualDataAction);
22 | expect(fetchedState()).toStrictEqual(toCompare);
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/MIT.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 PRATAP
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.
--------------------------------------------------------------------------------
/src/components/DetailsPage.js:
--------------------------------------------------------------------------------
1 | import { NavLink } from 'react-router-dom';
2 | import { FcPrevious } from 'react-icons/fc';
3 | import { useSelector } from 'react-redux';
4 | import { FaPiggyBank } from 'react-icons/fa';
5 | import Header from './Header';
6 |
7 | const DetailsPage = () => {
8 | const individualData = useSelector((state) => state.getIndividualDataReducer);
9 |
10 | return (
11 | <>
12 |
16 |
17 |
18 |
19 |
20 |
21 | Showing Statistics:
22 |
23 | {individualData.data.length}
24 |
25 |
26 |
27 |
28 | | Date |
29 | Net Asset Value |
30 |
31 | {
32 | individualData.data.map((item) => (
33 |
34 | | {item.date} |
35 | {item.nav} |
36 |
37 | ))
38 | }
39 |
40 | >
41 | );
42 | };
43 |
44 | export default DetailsPage;
45 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mutual-funds",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@reduxjs/toolkit": "^1.8.5",
7 | "@testing-library/jest-dom": "^5.16.5",
8 | "@testing-library/react": "^13.4.0",
9 | "@testing-library/user-event": "^13.5.0",
10 | "axios": "^0.27.2",
11 | "npm": "^8.19.2",
12 | "prop-types": "^15.8.1",
13 | "react": "^18.2.0",
14 | "react-dom": "^18.2.0",
15 | "react-icons": "^4.4.0",
16 | "react-redux": "^8.0.4",
17 | "react-router-dom": "^6.4.1",
18 | "react-scripts": "5.0.1",
19 | "web-vitals": "^2.1.4"
20 | },
21 | "scripts": {
22 | "start": "react-scripts start",
23 | "build": "react-scripts build",
24 | "test": "react-scripts test",
25 | "eject": "react-scripts eject"
26 | },
27 | "eslintConfig": {
28 | "extends": [
29 | "react-app",
30 | "react-app/jest"
31 | ]
32 | },
33 | "browserslist": {
34 | "production": [
35 | ">0.2%",
36 | "not dead",
37 | "not op_mini all"
38 | ],
39 | "development": [
40 | "last 1 chrome version",
41 | "last 1 firefox version",
42 | "last 1 safari version"
43 | ]
44 | },
45 | "devDependencies": {
46 | "@babel/core": "^7.19.3",
47 | "@babel/eslint-parser": "^7.19.1",
48 | "@babel/plugin-syntax-jsx": "^7.18.6",
49 | "@babel/preset-env": "^7.19.3",
50 | "@babel/preset-react": "^7.18.6",
51 | "eslint": "^7.32.0",
52 | "eslint-config-airbnb": "^18.2.1",
53 | "eslint-plugin-import": "^2.26.0",
54 | "eslint-plugin-jsx-a11y": "^6.6.1",
55 | "eslint-plugin-react": "^7.31.8",
56 | "eslint-plugin-react-hooks": "^4.6.0",
57 | "netlify-cli": "^12.0.4",
58 | "stylelint": "^13.13.1",
59 | "stylelint-config-standard": "^21.0.0",
60 | "stylelint-csstree-validator": "^1.9.0",
61 | "stylelint-scss": "^3.21.0"
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Metrics Webapp - Mututal Funds
4 |
5 | This React Capstone Project is about building a Mobile Web Application to check a list of metrics (numeric values) that are built with React and Redux.
6 |
7 | Select an API that provides numeric data about a topic and then build the webapp around it.
8 |
9 | ## Link to Live Demo
10 |
11 | [Loom Link](https://www.loom.com/share/3ae06abf18ee4831acdcc5610741caeb)
12 |
13 | ## Built With
14 |
15 | - React & Redux
16 |
17 | ## Netlify Link
18 |
19 | - [Netlify Link](https://metrics-app-mutual-funds-panabaka.netlify.app/)
20 |
21 | ## Preview of the Mutual Funds App
22 | 
23 | 
24 | 
25 |
26 |
27 |
28 | ## Getting Started
29 |
30 | To get a local copy up and running follow these simple example steps.
31 |
32 | ````
33 | git clone https://github.com/PRATAP-KUMAR/metrics-webapp-mutual-funds
34 | cd metrics-webapp-mutual-funds
35 | npm start
36 | ````
37 |
38 | ## Author
39 |
40 | 👤 **PRATAP PANABAKA**
41 |
42 | - GitHub: [@PRATAP-KUMAR](https://github.com/PRATAP-KUMAR)
43 | - Twitter: [@PRATAP_TWT](https://twitter.com/PRATAP_TWT)
44 | - Linkedin: [@LinkedIn](https://www.linkedin.com/in/pratap-kumar-panabaka-755489236/)
45 |
46 |
47 | ## 🤝 Contributing
48 |
49 | Contributions, issues, and feature requests are welcome!
50 |
51 | Feel free to check the [issues page](../../issues/).
52 |
53 | ## Show your support
54 |
55 | Give a ⭐️ if you like this project!
56 |
57 | ## Acknowledgments
58 |
59 | - Original Design is by the Author [Nelson Sakwa on Behance](https://www.behance.net/sakwadesignstudio)
60 |
61 | ## 📝 License
62 |
63 | This project is [MIT](./MIT.md) licensed.
64 |
--------------------------------------------------------------------------------
/.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@v2
14 | - uses: actions/setup-node@v1
15 | with:
16 | node-version: "12.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 .
24 | stylelint:
25 | name: Stylelint
26 | runs-on: ubuntu-22.04
27 | steps:
28 | - uses: actions/checkout@v2
29 | - uses: actions/setup-node@v1
30 | with:
31 | node-version: "12.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@v2
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
46 |
--------------------------------------------------------------------------------
/src/components/CallAPI.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react';
2 | import { useDispatch, useSelector } from 'react-redux';
3 | import { NavLink } from 'react-router-dom';
4 | import PropTypes from 'prop-types';
5 | import { FcPrevious, FcNext } from 'react-icons/fc';
6 | import { FaPiggyBank } from 'react-icons/fa';
7 | import { getIndividualDataAction } from '../redux/individual/individual';
8 | import Header from './Header';
9 | import './style.css';
10 |
11 | const CallAPI = ({ id }) => {
12 | const individualData = useSelector((state) => state.getIndividualDataReducer);
13 | const dispatch = useDispatch();
14 |
15 | useEffect(() => {
16 | dispatch(getIndividualDataAction(id));
17 | }, [dispatch, id]);
18 |
19 | return (
20 | <>
21 |
22 |
27 |
28 |
29 |
30 |
31 |
32 | Available Data:
33 |
34 | {individualData.data.length}
35 |
36 |
37 |
38 | SCHEME CODE -
39 | {individualData.meta.scheme_code}
40 | DETAILS
41 |
42 |
43 |
44 | Fund House:
45 | {individualData.meta.fund_house}
46 |
47 |
48 |
49 |
50 | Scheme Name:
51 | {individualData.meta.scheme_name}
52 |
53 |
54 |
55 |
56 | Scheme Type:
57 | {individualData.meta.scheme_type}
58 |
59 |
60 |
61 |
62 | Scheme Category:
63 | {individualData.meta.scheme_category}
64 |
65 |
66 |
67 | >
68 | );
69 | };
70 |
71 | CallAPI.propTypes = { id: PropTypes.string.isRequired };
72 |
73 | export default CallAPI;
74 |
--------------------------------------------------------------------------------
/src/components/HomePage.js:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react';
2 | import { useDispatch, useSelector } from 'react-redux';
3 | import { NavLink } from 'react-router-dom';
4 | import PropTypes from 'prop-types';
5 | import { RiFundsBoxFill } from 'react-icons/ri';
6 | import { FcNext } from 'react-icons/fc';
7 | import { getDataAction } from '../redux/imf/imf';
8 | import getExternalFunction from '../externalFunction';
9 | import Header from './Header';
10 |
11 | const HomePage = ({ handleId }) => {
12 | const imfData = useSelector((state) => state.imfReducer);
13 | const dispatch = useDispatch();
14 |
15 | const [value, setValue] = useState('');
16 | const handleInputChange = (e) => setValue(e.target.value);
17 |
18 | useEffect(() => {
19 | if (imfData.length === 0) {
20 | dispatch(getDataAction());
21 | }
22 | }, [dispatch, imfData.length]);
23 |
24 | if (imfData.length === 0) {
25 | return (
26 |
27 | INDIAN MUTUAL FUNDS
28 |
29 | PAGE IS LOADING...
30 |
31 | PLEASE WAIT
32 |
33 | );
34 | }
35 |
36 | return (
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | FUNDING GROUPS:
45 |
46 | {imfData.length}
47 |
48 |
49 |
50 |
58 |
59 |
60 | TOTAL STATS
61 |
62 |
63 | {
64 | getExternalFunction(imfData, 500)
65 | .filter((item) => item.schemeName.toLowerCase().includes(value.toLowerCase()))
66 | .map((item) => (
67 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | {item.schemeName}
79 |
80 |
81 | {item.schemeCode}
82 |
83 |
84 |
85 |
86 | ))
87 | }
88 |
89 |
90 | );
91 | };
92 |
93 | HomePage.propTypes = {
94 | handleId: PropTypes.func.isRequired,
95 | };
96 |
97 | export default HomePage;
98 |
--------------------------------------------------------------------------------
/src/components/style.css:
--------------------------------------------------------------------------------
1 | @media only screen and (max-width: 2000px) {
2 | .loading {
3 | background-color: #43aadd;
4 | display: flex;
5 | justify-content: center;
6 | width: 100%;
7 | height: 100%;
8 | }
9 |
10 | .header {
11 | display: flex;
12 | gap: 5rem;
13 | height: 4rem;
14 | background: #054ea1;
15 | text-align: center;
16 | font-weight: bold;
17 | font-size: 1rem;
18 | justify-content: space-around;
19 | align-items: center;
20 | color: #fff;
21 | padding-left: 1rem;
22 | }
23 |
24 | .icons {
25 | display: flex;
26 | gap: 2rem;
27 | font-size: 1.5rem;
28 | justify-content: flex-end;
29 | padding-right: 1rem;
30 | }
31 |
32 | .banner {
33 | background-color: #43aadd;
34 | display: flex;
35 | justify-content: center;
36 | height: 20rem;
37 | align-items: center;
38 | padding: 0 2rem;
39 | }
40 |
41 | .logo,
42 | .text-banner {
43 | display: flex;
44 | justify-content: center;
45 | flex: 0.5;
46 | }
47 |
48 | .search-bar {
49 | display: flex;
50 | border: 2px solid #122471;
51 | }
52 |
53 | .search-box {
54 | width: 100%;
55 | text-align: center;
56 | font-size: 1rem;
57 | margin: 0 auto;
58 | height: 2rem;
59 | background-color: #054ea1;
60 | color: #fff;
61 | border: none;
62 | }
63 |
64 | .search-bar > ::placeholder {
65 | color: #c2bbbb;
66 | }
67 |
68 | .stats {
69 | background-color: #122471;
70 | font-weight: bold;
71 | color: #fff;
72 | padding-left: 1rem;
73 | line-height: 2rem;
74 | }
75 |
76 | .banner-mp {
77 | flex: 0.5;
78 | text-align: right;
79 | display: flex;
80 | background-color: #43aadd;
81 | justify-content: space-between;
82 | height: 20rem;
83 | align-items: center;
84 | padding: 0 2rem;
85 | }
86 |
87 | .text-banner {
88 | flex: 0.5;
89 | font-size: 1.5rem;
90 | font-weight: bold;
91 | color: #fff;
92 | text-align: left;
93 | }
94 |
95 | .container {
96 | display: grid;
97 | grid-template-columns: 1fr 1fr;
98 | align-items: center;
99 | background-color: #e1e1e1;
100 | }
101 |
102 | .card {
103 | display: flex;
104 | flex-direction: column;
105 | justify-content: space-around;
106 | padding: 0 2rem;
107 | background-color: #054ea1;
108 | height: 15rem;
109 | border: 0.2px solid #43aadd;
110 | }
111 |
112 | .next-arrow {
113 | text-align: right;
114 | }
115 |
116 | .text {
117 | font-size: 1.2rem;
118 | font-weight: bold;
119 | color: #fff;
120 | text-align: right;
121 | }
122 |
123 | .subtext {
124 | font-size: 0.8rem;
125 | color: #fff;
126 | text-align: right;
127 | }
128 |
129 | .card:nth-child(2),
130 | .card:nth-child(3n) {
131 | background-color: #122471;
132 | }
133 |
134 | .card-mp {
135 | display: flex;
136 | padding: 2rem;
137 | background-color: #054ea1;
138 | height: 2.5rem;
139 | border: 0.2px solid #43aadd;
140 | justify-content: flex-start;
141 | }
142 |
143 | .card-mp .text {
144 | text-align: left;
145 | }
146 |
147 | .card-mp:nth-child(odd) {
148 | background-color: #122471;
149 | }
150 |
151 | .card-dp {
152 | display: flex;
153 | padding: 2rem;
154 | background-color: #054ea1;
155 | height: 2.5rem;
156 | border: 0.2px solid #43aadd;
157 | justify-content: flex-start;
158 | }
159 |
160 | .details-page {
161 | text-align: center;
162 | }
163 |
164 | .table {
165 | width: 100%;
166 | color: #fff;
167 | }
168 |
169 | .table,
170 | th,
171 | td {
172 | border: 2px solid #43aadd;
173 | border-collapse: collapse;
174 | }
175 |
176 | th {
177 | background-color: #054ea1;
178 | }
179 |
180 | tr {
181 | background-color: #054ea1;
182 | text-align: center;
183 | }
184 |
185 | tr:nth-child(even) {
186 | background-color: #122471;
187 | }
188 |
189 | .z-index {
190 | z-index: 9;
191 | }
192 | }
193 |
--------------------------------------------------------------------------------