Steroids React Boilerplate tutorial

This article provides an example of creating an application using the Steroids React Boilerplate. The application consists of two pages - Profile and Settings. The Profile page contains a card with user data, which can be created using a form on the Settings page.

So, let's start creating our application. Before we begin, we need to have a cloned repository of Steroids React Boilerplate. The boilerplate project is running in development mode. For more details on how to do this, you can refer to the article Quick Start.

To begin, let's add to the route tree, located in the routes/index.ts file, the profile page and the settings page. You can read more about the route tree in the article on Routing.

After adding the corresponding pages, the route tree looks like this:

import {IRouteItem} from '@steroidsjs/core/ui/nav/Router/Router';
import IndexPage from './IndexPage';
import ProfileGeneral from './ProfileGeneral';
import ProfileSettings from './ProfileSettings';

export const ROUTE_ROOT = 'root';
export const ROUTE_PROFILE_GENERAL = 'general';
export const ROUTE_PROFILE_SETTINGS = 'settings';

const roles = [null];

export default {
    id: ROUTE_ROOT,
    exact: true,
    path: '/',
    redirectTo: ROUTE_PROFILE_SETTINGS,
    label: __('Main Page'),
    component: IndexPage,
    roles,
    items: {
        [ROUTE_PROFILE_GENERAL]: {
            label: __('Profile Page'),
            path: '/general',
            component: ProfileGeneral,
       },
       [ROUTE_PROFILE_SETTINGS]: {
            label: __('Settings'),
            path: '/settings',
            component: ProfileSettings,
            isNavVisible: false,
        },
    },
} as IRouteItem;

Next, we need to check if we are on the settings page. To do this, make changes to the src/shared/Layout file.

// 'shared/Layout/Layout.tsx'
import {useBem, useSelector} from '@steroidsjs/core/hooks';
import {Notifications} from '@steroidsjs/core/ui/layout';
import Header from '@steroidsjs/core/ui/layout/Header';
import Portal from '@steroidsjs/core/ui/layout/Portal';
import ModalPortal from '@steroidsjs/core/ui/modal/ModalPortal';
import {getRoute} from '@steroidsjs/core/reducers/router';

import {ROUTE_ROOT} from '../../routes';
import './Layout.scss';

export default function Layout(props: React.PropsWithChildren<any>) {
    const bem = useBem('Layout');

    const isSettingsRoute = useSelector(getRouteId) === ROUTE_PROFILE_SETTINGS;

    if (isSettingsRoute) {
        return (
            <div className={bem.block('settings')}>
                <Notifications />
                <ModalPortal />
                <main role="main">
                    {props.children}
                </main>
            </div>
        );
    }

    return (
        <div className={bem.block()}>
            <Header
                logo={{
                    title: 'Steroids Demo',
                }}
                nav={{
                    items: ROUTE_ROOT,
                }}
            />
            <div className={bem.element('content')}>
                <Notifications />
                {props.children}
                <ModalPortal />
                {
                    process.env.IS_SSR
                        ? null
                        : <Portal />
                }
            </div>
        </div>
    );
}

Now let's create the profile page and settings page. All pages are located in the src/routes/ folder. Each page or component is placed in a separate folder and should contain two files — tsx and scss, as well as an index.ts file for shorter imports of created components. More details about the file structure can be found in the article "Project Architecture" in the React Components section.

On the profile page, we will check if there is filled profile data in the redux store, and if there is, we will display it using the <Card/> component. If there is no data, the user is prompted to create a profile.

// 'routes/ProfilePage/ProfilePage.tsx'
import useBem from '@steroidsjs/core/hooks/useBem';
import {Card} from '@steroidsjs/core/ui/content';
import {useDispatch, useSelector} from '@steroidsjs/core/hooks';
import {goToRoute} from '@steroidsjs/core/actions/router';
import {formSelector} from '@steroidsjs/core/reducers/form';

import {FORM_ID} from '../ProfileSettings/ProfileSettings';
import {ROUTE_PROFILE_SETTINGS} from '../index';
import './ProfileGeneral.scss';

export default function ProfilePage() {
    const bem = useBem('ProfilePage');
    const dispatch = useDispatch();

    const formValues = useSelector(state => formSelector(state, FORM_ID, ({values}) => values));

    return (
        <div className={bem.block()}>
            {formValues ? (
                    <Card
                        className='card'
                        header={{
                            avatar: {
                                src: 'https://i.ibb.co/T4j2NMQ/20230325210515-1.jpg',
                                status: true,
                            },
                            head: formValues.name,
                            subhead: formValues.surname,
                        }}
                        title={formValues?.about && __('About')}
                        description={formValues?.about ?? null}
                        buttons={[
                            {
                                label: __('Edit'),
                                onClick: () => {
                                    dispatch(goToRoute(ROUTE_PROFILE_SETTINGS));
                                },
                            },
                        ]}
                    />
                )
                : (
                    <div className={bem.element('empty')}>
                        <Button
                            label={__('Create Profile')}
                            onClick={() => dispatch(goToRoute(ROUTE_PROFILE_SETTINGS))}
                        />
                    </div>
                )}
        </div>
    );
}

To create a profile, we need a corresponding page. Let's create the SettingsPage and add a form for creating and editing the profile.

// 'routes/SettingsPage/SettingsPage.tsx'
import useBem from '@steroidsjs/core/hooks/useBem';
import { useDispatch } from '@steroidsjs/core/hooks';
import { Button, Form, InputField, TextField } from '@steroidsjs/core/ui/form';
import { goToRoute } from '@steroidsjs/core/actions/router';

import { ROUTE_PROFILE_GENERAL } from '../index';
import './SettingsPage.scss';

export const FORM_ID = 'ProfileSettings';

export default function SettingsPage() {
    const bem = useBem('SettingsPage');
    const dispatch = useDispatch();

    return (
        <div className={bem.block()}>
            <Form
                formId={FORM_ID}
                useRedux
                className={bem.element('form')}
                onSubmit={() => dispatch(goToRoute(ROUTE_PROFILE_GENERAL))}
            >
                <h2 className={bem.element('title')}>{__('Create Profile')}</h2>
                <InputField
                    attribute='name'
                    label={__('First Name')}
                    required
                />
                <InputField
                    attribute='surname'
                    label={__('Last Name')}
                    required
                />
                <TextField
                    attribute='about'
                    label={__('About Yourself')}
                    required
                />
                <Button
                    type='submit'
                    label='Save'
                />
            </Form>
        </div>
    );
}

Upon submission, the transition to the profile page occurs, and the form fields are saved in the redux store thanks to the useRedux flag.

And that's it! Thank you for trying out the Steroids React Boilerplate. We hope this guide helps you kickstart the development of your web application using the Steroids framework.