Auth Containers

We have authenticated our users, but now they're stuck on the login screen. This chapter is about building re-usable containers to redirect users to authorized pages.

Auth containers#

Our app has a /graphics route, that lists all the graphics a user has created. This will be our root private route - ie a user will be redirected here as soon as she logs in.

For common components like navigation, auth containers, rich text editors and so on, we'll use the app.components.* namespace. This means we'll have three top-level namespaces:

  • app.domain.* for domain-specific functionality

  • app.pages.* for top-level routes and

  • app.components.* for shared components

We'd like to point out again that this is only one way you could do it - feel free to experiment with different structuring for your apps.

Public container#

Let's define a public component app.components.auth/public that will wrap /login and /register route components.

The job of this component is to listen to :a.d.f/me and redirect the user to /graphics route as soon as she logs in. If the user is not logged in, it renders the children (ie the login form):

The public component subscribed to :a.d.f/me defined in the last chapter redirects to /graphics if a user is logged in.

The argument to the public function, children, should not be confused with props.children. This is a Reagent component. The children in this case means the vector of divs that make up the login page.

We use & children to allow for multiple Hiccup forms like:

If we used children in place of & children, Reagent would only render the last form and ignore all others, ie it would only render [:div "form 2"] in the example above.

:<> is the shorthand for React Fragment. In React, a component can return only one form. Since we allow the children to be a list of forms, we wrap it in a Fragment so React doesn't complain.

The Redirect component from React Router is used to perform the Redirect using a component.

If we wrap the :a.p.login component with auth/public after we :require it, we will get redirected to /graphics on successful login:

Notice how all components are now wrapped under auth/public. The above example is truncated, you will have more lines of code in your component.

We created a test user while setting up Firebase. Try to log in with the test credentials and you'll be redirected to /graphics route.

Redirected on successful login

After logging in, if you try to visit /login by manually altering the URL, the app will redirect you to /graphics.

Top navigation and logout UI#

It's standard to have a top global nav with some details about the user and associated actions, such as settings, profile, and logout.

Since our users can now log in, let's make them feel at home by showing their email and a logout option. We'll use Blueprint's Navbar component.

Blueprint's Navbar has support to align items to the left or right, add headings, dividers, and much more. We recommend checking the component props if you'd like to learn more.

We will create a Navbar wrapper and call it Nav. Nav will be used throughout the application - ie it belongs to app.components.nav namespace. We are going to define app.components.nav/top component for the top navigation. In an application with multiple nav bars, multiple components can be defined in this namespace:

  • we subscribe to the logged-in user

  • bg-pink-200 sets the nav background to a shade of pink (you can try other colors)

  • (.-Group Navbar) is equal to Navbar.Group

  • the :align prop helps align the group to either left or right

  • we render a Navbar.Heading in the left group

  • we render two buttons in the right group

  • the logout button dispatches :a.d.f/logout event (which we haven't created yet)

 

This page is a preview of Tinycanva: Clojure for React Developers

Please select a discussion on the left.