Skip to content

Building a login screen

We are going to build a login screen for an Ionic React app.

If you need help setting up a React project, please refer to the React documention.

A simpler HTML page with just login and password form is here at JSFiddle.

Helper Storage Component

First, We are going to create some helper functions to store the credentials in our app. Save these codes in a file, Storage.tsx.

import {} from '@ionic/react';
import { Plugins } from '@capacitor/core';
const { Storage } = Plugins;
const set_storage = async (key: string, data: any) => {
    let item = {
        key: key,
        value: JSON.stringify(data)
    }
    await Storage.set(item);
}
const get_storage = async (key: string) => {
    const ret_str: any = await Storage.get({key: key});
    let value = ret_str.value;
    let ret: any;
    try {
        ret = JSON.parse(value);
    }
    catch(e) {
        return null;
    }

    return ret;
}

const remove_storage = async (key:string) => {
    await Storage.remove({ key: key });
}

export { get_storage, set_storage, remove_storage };

Login Screen

As we have already seen in our Quick Start example, the authentication with the TACTIC server is done using the following piece of codes:

let server = TACTIC.get();
server.set_server(server_url);
server.set_project(project);
let ticket = '';
ticket = server.get_ticket(email, password);

In the following Ionic React code sample, we are creating a login screen with a form to enter user name and password to authenticate against a TACTIC server.

import React from 'react'
import { useState } from 'react'

import {
  IonContent,
  IonHeader,
  IonPage,
  IonTitle,
  IonToolbar,
  IonButtons,
  IonRow,
  IonMenuButton,
  IonCol,
  IonIcon,
  IonGrid,
  IonItem,
  IonInput,
  IonLabel,
  IonButton,
  useIonViewWillEnter,
} from "@ionic/react";
import { useHistory } from 'react-router-dom';

import { get_storage, set_storage } from './Storage';

import LogOut from './Logout';  // This is left without implementation in this example.

import { TACTIC, spt } from "../assets/js/tactic.js";

const LogIn: React.FC = () => {

    const [email, setEmail] = useState<string>()

    const [password, setPassword] = useState<string>()
    const [server_url, setServer] = useState<string>("https://portal.southpawtech.com")
    const [site, setSite] = useState<string>("trial")
    const [project, setProject] = useState<string>("apt_test")

    const [credentials, setCredentials] = useState<any[any]>()

    const [loggedInTicket, setLoggedInTicket] = useState<string>()

    useIonViewWillEnter( () => {

      get_storage("credentials").then((val) => {
        if (val) {
          setServer(val.server_url);
          setEmail(val.email);
          setLoggedInTicket(val.login_ticket);
        }
      });

    });

    const [errorMsg, setErrMsg] = useState<string>()

    const history = useHistory()

    // Handling login button
    const handleLogin = async () => {

      // Authenticating TACTIC server and getting the ticket
      let server = TACTIC.get();
      server.set_server(server_url);
      server.set_project(project);

      let ticket = '';

      try {

        ticket = server.get_ticket(email, password);

        server.set_ticket(ticket);

        setErrMsg('Log in successful.')
        setPassword("")

        const credentials = {
          'server_url': server_url,
          'email': email,
          'login_ticket': ticket,
          'project': project,
          'site': site

        }
        setCredentials(credentials);
        set_storage("credentials", credentials);

      }
      catch(e) {
        setErrMsg(e);
      }
    };

    const isLoggedIn = () => {
      if (loggedInTicket) {
        return(
          <IonRow>
            <IonCol>
              <LogOut />
            </IonCol>
          </IonRow>
        );
      }
      return (
        <IonRow>
          <IonCol>
            <IonButton expand="block" onClick={handleLogin}>
              Login
            </IonButton>
          </IonCol>
        </IonRow>
      );
    }

    const userName = () => {
      if (loggedInTicket) {
        return (null);
      }
      return (
        <IonRow>
          <IonCol>
            <IonItem>
              <IonLabel position="floating"> User Name</IonLabel>
              <IonInput
                type="email"
                value={email}
                onIonChange={(e) => setEmail(e.detail.value!)}
              ></IonInput>
            </IonItem>
          </IonCol>
        </IonRow>
      );
    }

    const userPasswd = () => {
      if (loggedInTicket) {
        return (null);
      }
      return (
        <IonRow>
          <IonCol>
            <IonItem>
              <IonLabel position="floating"> Password</IonLabel>
              <IonInput
                type="password"
                value={password}
                onIonChange={(e) => setPassword(e.detail.value!)}
              ></IonInput>
            </IonItem>
          </IonCol>
        </IonRow>
      );
    }


    return (
      <IonPage>
        <IonHeader>
          <IonToolbar>
            <IonButtons slot="start">
              <IonMenuButton />
              <IonTitle>Login</IonTitle>
            </IonButtons>
          </IonToolbar>
        </IonHeader>

        <IonContent fullscreen className="ion-padding ion-text-center">
          <IonGrid>

            { userName() }

            { userPasswd() }

            { isLoggedIn() }

            <IonRow>
              <IonCol>
                <p>{errorMsg}</p>
              </IonCol>
            </IonRow>
          </IonGrid>
        </IonContent>
      </IonPage>
    );
}

export default LogIn;