onBootstrap static method

Widget onBootstrap(
  1. BuildContext context,
  2. dynamic complete(
    1. bool
    )
)

Implementation

static Widget onBootstrap(
  BuildContext context,
  Function(bool) complete,
) {
  final organizationsService = context.read<OrganizationService>();
  final feature = OrganizationFeature.instance();

  return Consumer<nav.RootState>(
    builder: (context, state, _) {
      return FutureBuilder(
        future: organizationsService.loadOrgs(),
        builder: (context, snapshot) {
          final l10n = context.l10n;

          if (snapshot.connectionState == ConnectionState.done) {
            final organizations = snapshot.data;
            if (organizations == null) {
              // if no organization list is returned then
              // an error occurred and the user should be
              // be logged out and an error message
              // displayed
              state.setBusy();
              UserIdentityFeature.logout();
            } else {
              // Determine the default organization
              // from the list of organizations
              final defaultOrg = UserIdentityFeature.getDefaultOrg();
              Organization? organization;
              for (final org in organizations) {
                if (org.orgId == defaultOrg) {
                  organization = org;
                  break;
                }
              }

              if (feature.config.membershipRequired) {
                // if membership is required then ensure
                // the user is associated with an organization
                if (organizations.isEmpty) {
                  // if the user is not associated with any
                  // organizations then show the create
                  // organization dialog.
                  return OrganizationProfile(
                    buildContainer: (child, width, height) {
                      return SizedBox(
                        width: width + 40, // margins (4*2) + padding (16*2)
                        height: height + 40, // margins (4*2) + padding (16*2)
                        child: Card(
                          child: Padding(
                            padding: const EdgeInsets.all(16.0),
                            child: child,
                          ),
                        ),
                      );
                    },
                    dismissDialog: () {
                      state.setBusy();
                      UserIdentityFeature.logout();
                      Future.microtask(() => complete(false));
                    },
                    createOrgOnly: true,
                  );
                } else if (organization == null) {
                  // if membership is required then the user must
                  // be associated with at least one organization
                  // and a default must be set.

                  // pick the first verified organization or the
                  // first organization if none are verified
                  organization = organizations.firstWhere(
                    (org) => org.isVerified,
                    orElse: () => organizations.first,
                  );
                  return BootstrapNotification.buildNotification(
                    title: feature.getLocalizedValue(
                      context,
                      'defaultOrganizationSet',
                    ),
                    body: l10n.defaultOrganizationSetNotification,
                    dialogSize: BootstrapNotification.dialogSize(480, 188),
                    logout: () {
                      UserIdentityFeature.setDefaultOrg(
                        organization!.orgId,
                        logout: true,
                      );
                      Future.microtask(() => complete(false));
                    },
                  );
                }
              }

              if (organization != null) {
                dismissDialog() {
                  if (feature.config.canChangeDefaultOrg &&
                      (organizations.length > 1 ||
                          !feature.config.membershipRequired)) {
                    // if there are multiple organizations then
                    // set the default organization to an empty
                    // string and log out the user so they can
                    // select a new organization
                    state.setBusy();
                    UserIdentityFeature.setDefaultOrg(
                      '',
                      logout: true,
                    );
                  } else {
                    // if there is only one organization then
                    // log out the user without changing the
                    // default organization
                    UserIdentityFeature.logout();
                  }
                  Future.microtask(() => complete(false));
                }

                if (!organization.isVerified) {
                  // if the organization is not verified then show the
                  // unverified organization alert dialog and allow the
                  // user to logout
                  return BootstrapNotification.buildNotification(
                    title: feature.getLocalizedValue(
                      context,
                      'unverifiedTitle',
                    ),
                    body: l10n.awaitingVerification(
                      feature.getLocalizedValue(
                        context,
                        'orgTypeText',
                      ),
                      organization.name,
                    ),
                    dialogSize: BootstrapNotification.dialogSize(480, 272),
                    logout: dismissDialog,
                  );
                }

                // if the feature has a subscription active status
                // pattern configured then check if the organization
                // in context has a valid subscription
                final activeStatusPattern =
                    feature.config.billing?.activeStatusPattern;
                if (activeStatusPattern != null) {
                  final status = organization.subscriptionStatus?.name;
                  if (status == null ||
                      !RegExp(
                        activeStatusPattern,
                      ).hasMatch(
                        status,
                      )) {
                    final billingFeature = FeatureRegistry.instance()
                        .getFeature<BillingFeature>(
                            BillingFeature.featureName);

                    if (billingFeature == null || !organization.isOwner) {
                      // if the organization has no active subscription
                      // then show the inactive subscription alert
                      // dialog and log out the user
                      return BootstrapNotification.buildNotification(
                        title: feature.getLocalizedValue(
                          context,
                          'noActiveSubscription',
                        ),
                        body: l10n.noActiveSubcriptionForOrganization,
                        dialogSize:
                            BootstrapNotification.dialogSize(480, 209),
                        logout: dismissDialog,
                      );
                    } else {
                      final product =
                          feature.config.billing?.productName != null
                              ? billingFeature.getBillingProduct(
                                  feature.config.billing!.productName,
                                )
                              : null;
                      assert(
                        product != null,
                        'Product not found for product name: '
                        '${feature.config.billing!.productName}',
                      );

                      return billingFeature.planSelectionDialogCard(
                        context,
                        product!,
                        subtitle: feature.getLocalizedValue(
                          context,
                          'orgBillingPlanSubtitleBootstrap',
                        ),
                        orgId: organization.orgId,
                        currentPlanId: organization.subscriptionPlan,
                        currentSubscriptionId: organization.subscriptionId,
                        currentPlanStatus: organization.subscriptionStatus,
                        dismissOnPaymentTimeout: true,
                        waitForPaymentCompletion:
                            _waitForSubscriptionActivation(
                          context,
                          organization,
                          complete,
                        ),
                        dismissDialog: dismissDialog,
                      );
                    }
                  }

                  // load the organization details and complete
                  // the bootstrapping process once the details
                  // are loaded
                  organizationsService.readOrgData(organization).then((_) {
                    Future.microtask(() => complete(true));
                  });
                  return const SizedBox();
                }
              }
            }
            // bootstrapping is complete and
            // the user can proceed to the app
            Future.microtask(() => complete(true));
            return const SizedBox();
          } else {
            // show loading indicator while
            // organizations user is associated
            // with are being loaded
            return const CircularProgressIndicator();
          }
        },
      );
    },
  );
}