slovnicki / beamer

A routing package built on top of Router and Navigator's pages API, supporting arbitrary nested navigation, guards and more.
MIT License
591 stars 129 forks source link

[Help/Question] How to implement router delegate having a login page and nested navigations page #603

Open Retr0sec7 opened 1 year ago

Retr0sec7 commented 1 year ago

I'm having issues trying to create a router delegate on an application that has a login and nested navigations.

Flow: LoginPage() -> Authentication occurs, navigates to home page .-> HomePage()

So imagine my home page real similar to this example: beamer example nested navigation

This is the router navigation I'm currently using on my main:

final routerDelegate = BeamerDelegate(
    locationBuilder: (routeInformation, _) =>
        HomeViewLocation(routeInformation), // or LoginViewLocation() ? 
    guards: [
      BeamGuard(
        pathPatterns: ['/login', '/'],
        check: (context, location) =>
            context.read<AppBloc>().state.status ==
            AuthenticationStatus.unauthenticated,
        beamToNamed: (origin, target) => '/main-menu',
      ),
      BeamGuard(
        pathPatterns: ['/', '/main-menu'],
        check: (context, location) =>
            context.read<AppBloc>().state.status ==
            AuthenticationStatus.authenticated,
        beamToNamed: (origin, target) => '/login',
      ),
    ],
  );

HomeViewLocation beam lcoation navigaties to HomeWebLocation() which is the scaffold with the Home main header and it's beamer content locations.


class HomeViewLocation extends BeamLocation<BeamState> {
  HomeViewLocation(RouteInformation routeInformation) : super(routeInformation);

  @override
  List<String> get pathPatterns => ['/*'];

  @override
  List<BeamPage> buildPages(BuildContext context, BeamState state) => [
        const BeamPage(
          key: ValueKey('home'),
          child: WebHomeView(),
        )
      ];
}

The issue is that I can't navigate to the login Page now and I don't how make my app work that support a router delegate with my home page and a login view. I haven't created a BeamLocation for my login page. I tried to do it but I didn't know how to implement to use my Home location or login based on authentication status. Can someone give an example of how to handle this? Thanks.

vduseev commented 1 year ago

Hi @Retr0sec7, I recommend checking out this example: bottom_navigation_riverpod

In that example the guard is configured in an inverse manner:

guards: [
  BeamGuard(
    pathPatterns: ['/login'],
    guardNonMatching: true,
    check: (context, state) {
      return container.read(authStateControllerProvider);
    },
    beamToNamed: (origin, target, deepLink) => '/login',
  ),
],

Anything that does not match with the '/login' path pattern will trigger a guard check. It's important that other locations within navigation do not intersect with '/login'. For example, we can't use '/' as a home location in that case. That's why the example I've linked uses '/home' instead.