Blogging my journey of learning Full stack devlopment and creating an App to get a hands on knowledge.

Search This Blog

Thursday, 23 February 2023

Invoice Portal User Authentication with Auth0

 

Auth 0 Setup

Application > Create Application > Single Page Application

Updated following Details

Name: Invoice Portal App
Application logo: An URL of logo stored in S3 bucket
Allowed callback URL: http://localhost:3000
Allowed Logout URL: http://localhost:3000
Allowed Web Origins : http://localhost:3000
Allow Cross Origin Authentication : Enabled

React App


Update the files

//Index.js file
import { Auth0Provider } from "@auth0/auth0-react";
const onRedirectCallback = (appState) => {
  history.push(
    appState && appState.returnTo ? appState.returnTo : window.location.pathname
  );
};
const config = getConfig();
const providerConfig = {
  domain: config.domain,
  clientId: config.clientId,
  onRedirectCallback,
  authorizationParams: {
    redirect_uri: window.location.origin,
    ...(config.audience ? { audience: config.audience } : null),
  },
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
  <Auth0Provider  {...providerConfig}>
    <App />
  </Auth0Provider>
</React.StrictMode>

);

Auth0Provider : Auth0Provider stores the authentication state of your users and the state of the SDK — whether Auth0 is ready to use or not. It also exposes helper methods to log in and log out your users, which you can access using the useAuth0() hook.Wrap your root component, such as App, with Auth0Provider to integrate Auth0 with your React app.

The Auth0Provider component takes the following props:

domain and clientId: The values of these properties correspond to the "Domain" and "Client ID" values present under the "Settings" of the single-page application that you registered with Auth0.
onRedirectCallback() : Method to handle the event where Auth0 redirects your users from the Auth0 Universal Login page to your React application. You use the useHistory() hook to get the history object from React Router. You use the history.push() method to take users back to the route they intended to access before authentication.
authorizationParams.redirect_uri: The URL to where you'd like to redirect your users after they authenticate with Auth0.


//App.js
import { useAuth0 } from "@auth0/auth0-react";
const { isAuthenticated, isLoading } = useAuth0();
......

return (
         <Router>
            <NavigationBar />
            {/* if Authenticated load the Application pages */}
            {isAuthenticated && (
            <Routes>
              <Route exact path="/" element={<DashboardApp />} />
              <Route path="viewInvoices" element={<ListAllInvoices />} />
              <Route path="createInvoice" element={<CreateInvoice />} />
              <Route path="viewSingleInvoice" element={<ViewSingleInvoice />} />
              <Route path="userProfile" element={<Profile />} />
            </Routes>
          )} 
            {/* if not Authenticated load the Landing Page for Login or SignUp */}   
          {!isAuthenticated && (
              <Routes>
                <Route exact path="/" element={<LandingPage />} />
              </Routes>
            )
          }
          </Router>




//LoginButton.js Component
import React from 'react';
import { useAuth0 } from '@auth0/auth0-react';
import { Button } from '@mui/material';

const LoginButton = () => {
  const { loginWithRedirect } = useAuth0();
  return (
    <Button variant="contained" onClick={() => loginWithRedirect()}>Login</Button>
   
  );
};

export default LoginButton;



//Logout.js component
import React from 'react';
import { useAuth0 } from '@auth0/auth0-react';

const LogoutButton = () => {
  const { logout } = useAuth0();
  return (
    <button
      className="btn btn-danger btn-block"
      onClick={() =>
        logout({
          returnTo: window.location.origin,
        })
      }
    >
      Log Out
    </button>
  );
};

export default LogoutButton;



//Signup.js component
import React from 'react';
import { useAuth0 } from '@auth0/auth0-react';
import { Button } from '@mui/material';

const SignupButton = () => {
  const { loginWithRedirect } = useAuth0();
  return (
    <Button variant="outlined"
      onClick={() =>
        loginWithRedirect({
          screen_hint: 'signup',
        })
      }
    >
      Sign Up
    </Button>
  );
};

export default SignupButton;


Integrated the above components in invoice portal App.
Read More

Thursday, 16 February 2023

Invoice Portal Project Links

Read More

Useful React Hooks

 Hooks are the function that you hook it to your Functional App. Hooks can manage state's behavior and side effects by isolating them from a component.

Several of Useful Hooks are:

1.UseState

The useState hook is used to create a stateful function component that can be used with JSX.

const [state, updaterFunction] = useState('')

state:Returns current state value
updaterFunction : Updates the State value
useState: Whatever you put in the parenthesis is the default state


2.UseEffect

The useEffect hook has two parameters, the first parameter is the function we want to run while the second parameter is an array of dependencies. If the second parameter is not provided, the hook will run continuously and if the array contains any dependencies in it,the useEffect Hook will only run if one of those dependencies changes.

   useEffect(() =>{//function logic}, [])

With the useEffect hook, you're able to create side effects while maintaining the component's purity. Within this hook, you can send network requests, change the state value.

3.UseContext

The UseContext provides a way to share states or data throughout the React component tree. The main idea of using the context is to allow your components to access global data and re-render when that global data is changed. Context solves the props drilling problem: when you have to pass down props from parents to children. You can hold inside the context: global state, theme, application configuration, authenticated user name, user settings, preferred language.

// context.js
import { createContext } from 'react';
export const Context = createContext('Default Value');

 

 
//App.js
import { Context } from './context';
function App() {
  const value = 'My Context Value';
  return (
    <Context.Provider value={value}>
      <MyComponent />
    </Context.Provider>
  );

 

//MyComponent.js
import { useContext } from 'react';
import { Context } from './context';
function MyComponent() {
  const value = useContext(Context);
  return <span>{value}</span>;

}

The hook returns the value of the context: value = useContext(Context). The hook also makes sure to re-render the component when the context value changes.


4.useMemo

useMemo keeps a function from being executed again if it didn’t receive a set of parameters that were previously used. It returns the results of a function. Use it when you want to prevent some heavy or costly operations from being called on each render.

const memoizedResult = useMemo(() => expensiveComputation(a), [a])

Once memoized, the hook is going to return the memoized value without invoking expensivecomputation(a) unless value a is changed.


5.useCallback

useCallback keep a function from being re-created again, based on a list of dependencies. It returns the function itself. Use it when you want to propagate it to child components, and prevent from a costly function from re-running.

            const cachedFn = useCallback(function, dependencies)

React will give you the same function (not call the function ) again if the dependencies have not changed since the last render. 

6.useRef

useRef returns an object that can persist in an application. The hook has only one property, current, and we can easily pass an argument to it.

1. It allows you to persist values between renders.

const count = useRef(0);

{count.current}

2. Accessing DOM Elements

const inputElement = useRef();
const focusInput = () => {
    inputElement.current.focus();
  };
//render function
 <input type="text" ref={inputElement} />
 <button onClick={focusInput}>Focus Input</button>


3.Tracking State Changes

  const [inputValue, setInputValue] = useState("");
  const previousInputValue = useRef("");
  useEffect(() => {
  previousInputValue.current = inputValue;
  }, [inputValue]);

7.useHistory

It lets you access the history instance used by React Router. Using the history instance you can redirect users to another page. The history instance created by React Router uses a Stack( called “History Stack” ), that stores all the entries the user has visited.

const history = useHistory()
history.push("/dashboard")

8.useNavigate()

useNavigate is part of React Router and has replaced useHistory, although it is similar to useHistory, but with more useful features.

Uses:

Go to the previous or next pages

Redirect user to a specific Url

let navigate = useNavigate()

const handleClick = () => {

      navigate('/aboutpage') }

return(<button onClick={handleClick}> Read More </button>);}

 

Read More

Tuesday, 14 February 2023

Created API for Invoice Portal using AWS Lambda function and API Gateway

At first I decided to use MongoDB Atlas Data API for my Invoice Portal App to read and write data from MongoDB database. But during querying the Mongo Data API, it gave an CORS error.
So, MongoDB Data API only supports server apps and not browser app .In order to use it you have to implement another API in front of it to access it.

I wanted to learn and use AWS services ,so I thought of using AWS Lambda and API Gateway to create the APIs. 

Create a MockAPI using AWS Lambda function and API Gateway and test it in Postman.







AWS Lambda

1.     Created createInvoice function by connecting it to MongoDB database and using InsertOne                     function of MongoDB, to add data to the collection

        const result = await db.collection("Invoices").insertOne(JSON.parse(event.body));

2.    Created getSingleInvoice function and used find function of MongoDB, to find the requested                 Invoice based on path parameter InvoiceID in the API route.
        
         //Get the parameter invoiceID from the event to find the invoice from the DB
         var invoiceID = event.pathParameters.invoiceID;
     
        const invoice = await db.collection("Invoices").find({ "_id": new ObjectID(invoiceID)                              }).toArray();
3.    Created getAllInvoices function ,to get all the invoices from the DB
        
        const invoice = await db.collection("Invoices").find({}).toArray();

AWS API Gateway

1.    Create API
2.    Select HTTP API which has CORS support in it and Build it
3.    Add API Name and  in Add Integrations ,add Lambda functions that you created
4.    Configure routes select HTTP route method and route path based on what your function will be               doing
5.    Configure Access-Control-Allow-Origin to * i.e. ALL




API implementation code:


Read More

Wednesday, 1 February 2023

Featured Post

Invoice Portal Project Links

Web App link for Invoice Portal  Invoice Portal App lets an user view and create an Invoice. Features: View the list of Number of Invoices b...

Powered by Blogger.

Popular Posts