1. Frontend
  2. Code Structure

Some folders are structured in the following sections:

  • front: all front pages/components.
  • admin: user management and other admin tools.
  • core: main application components.
  • app: your SaaS implementation.

Folders

  • views: admin, core, app and front views.
  • router: admin, core, app and front routes.
  • store: account, app, auth, pricing, tenant and theme states.
  • services: app and core API or Fake API implementations.
  • locale: supported languages.
  • application: contracts, dtos, enums, pricing, sidebar.
  • components: app, core, front, layout and ui components.
  • plugins: axios middleware, logging and event bus.
  • utils: date, number and store utils...
  • assets: css, icons and img.

Views (Pages)

  • front: Landing, Pricing...
  • admin: Tenants/Index, Emails...
  • core: Dashboard, Members...
  • app: Contract/Index, NewContract...

Router

Using React and Svelte:

App.tsx
...
  return (
    <Router>
       <Routes>
        <Route path="/">
          <Route index element={<Landing />} />
          <Route path="/pricing" element={<Pricing />} />
          <Route path="/contact" element={<Contact />} />
          ...
        </Route>

        <Route path="/admin" element={<Navigate replace to="/admin/tenants" />} />
        <Route path="/admin" element={
            <PrivateRoute userTypes={[UserType.Admin]}>
                <AdminIndex />
            </PrivateRoute>
          }>
          <Route path="tenants" element={<AdminTenants />} />
          <Route path="tenant/:id" element={<AdminTenant />} />
          <Route path="users" element={<AdminUsers />} />
        </Route>
        ...

Using Vue2 and Vue3:

  • frontRoutes.ts: Landing, Pricing...
  • adminRoutes.ts: Tenants, Users...
  • coreRoutes.ts: Dashboard, Profile Settings...
  • appRoutes.ts: (Sample app) Contracts, Employees...

Store

  • accountState.ts
  • appState.ts
  • authState.ts
  • pricingState.ts
  • tenantState.ts
  • themeState.ts

Services

  • core: AuthenticationService.ts, FakeAuthenticationService.ts...
  • app: ContractService.ts, FakeContractService.ts...

Locale

Supported languages files with i18n.

Application

  • contracts: UserUpdateRequest, TenantCreateRequest...
  • dtos: UserDto, TenantDto...
  • enums: SubscriptionBillingPeriod, TenantUserRole...
  • pricing: Default pricing plans.
  • sidebar: Application sidebar menu.

Components

  • front Hero, Faq...
  • core NewMember, EditMember...
  • app ContractsList, employees...
  • layout SidebarLayout, StackedLayout...
  • ui ButtonPrimary, SuccessModal...

Plugins:

  • axiosMiddleware.js: Middleware to set up Bearer token, X-Tenant-Key using axios.
  • logging.ts: Using sentry.
  • tinyEventBus.ts: Event emitter library using tiny-emitter.

Utils

  • shared: DateUtils.ts, NumberUtils.ts...
  • store: PricingUtils.ts, TenantUtils.ts, UserUtils.ts...

Assets

  • css: Tailwind CSS file.
  • icons: IconContract, IconSign...
  • img: icon-dark.png, logo-dark.png...

Full code structure

|-- src
    |-- application
    |   |-- contracts
    |   |   |-- app
    |   |   |   |-- contracts
    |   |   |   |   |-- AddContractMemberDto.ts
    |   |   |   |   |-- ContractStatusFilter.ts
    |   |   |   |   |-- CreateContractRequest.ts
    |   |   |   |   |-- SendContractRequest.ts
    |   |   |   |   |-- UpdateContractRequest.ts
    |   |   |   |-- employees
    |   |   |       |-- CreateEmployeesRequest.ts
    |   |   |       |-- UpdateEmployeeRequest.ts
    |   |   |-- core
    |   |       |-- links
    |   |       |   |-- CreateLinkInvitationRequest.ts
    |   |       |   |-- CreateLinkRequest.ts
    |   |       |   |-- UpdateLinkRequest.ts
    |   |       |-- subscriptions
    |   |       |   |-- SelectedSubscriptionRequest.ts
    |   |       |   |-- SubscriptionCreateCardTokenRequest.ts
    |   |       |   |-- SubscriptionGetCurrentResponse.ts
    |   |       |   |-- SubscriptionUpdatePriceRequest.ts
    |   |       |   |-- SubscriptionUpdateProductRequest.ts
    |   |       |-- tenants
    |   |       |   |-- TenantCreateRequest.ts
    |   |       |   |-- TenantFeaturesDto.ts
    |   |       |   |-- TenantInvitationResponse.ts
    |   |       |   |-- TenantUpdateImageRequest.ts
    |   |       |   |-- TenantUpdateJoinSettingsRequest.ts
    |   |       |   |-- TenantUserUpdateRequest.ts
    |   |       |-- users
    |   |       |   |-- UserInviteRequest.ts
    |   |       |   |-- UserLoggedResponse.ts
    |   |       |   |-- UserLoginRequest.ts
    |   |       |   |-- UserRegisterRequest.ts
    |   |       |   |-- UserUpdateAvatarRequest.ts
    |   |       |   |-- UserUpdateLocaleRequest.ts
    |   |       |   |-- UserUpdatePasswordRequest.ts
    |   |       |   |-- UserUpdateRequest.ts
    |   |       |   |-- UserVerifyRequest.ts
    |   |       |-- workspaces
    |   |           |-- CreateWorkspaceRequest.ts
    |   |           |-- UpdateWorkspaceRequest.ts
    |   |-- dtos
    |   |   |-- EntityDto.ts
    |   |   |-- app
    |   |   |   |-- contracts
    |   |   |   |   |-- ContractActivityDto.ts
    |   |   |   |   |-- ContractDto.ts
    |   |   |   |   |-- ContractEmployeeDto.ts
    |   |   |   |   |-- ContractMemberDto.ts
    |   |   |   |-- employees
    |   |   |   |   |-- EmployeeDto.ts
    |   |   |   |-- usage
    |   |   |       |-- AppUsageSummaryDto.ts
    |   |   |-- core
    |   |   |   |-- AppEntityDto.ts
    |   |   |   |-- AppWorkspaceEntityDto.ts
    |   |   |   |-- MasterEntityDto.ts
    |   |   |   |-- email
    |   |   |   |   |-- EmailTemplateDto.ts
    |   |   |   |-- links
    |   |   |   |   |-- LinkDto.ts
    |   |   |   |   |-- LinkInvitationDto.ts
    |   |   |   |-- subscriptions
    |   |   |   |   |-- SubscriptionCardDto.ts
    |   |   |   |   |-- SubscriptionCouponDto.ts
    |   |   |   |   |-- SubscriptionCustomerDto.ts
    |   |   |   |   |-- SubscriptionFeatureDto.ts
    |   |   |   |   |-- SubscriptionInvoiceDto.ts
    |   |   |   |   |-- SubscriptionInvoiceLineDto.ts
    |   |   |   |   |-- SubscriptionPaymentMethodDto.ts
    |   |   |   |   |-- SubscriptionPlanDto.ts
    |   |   |   |   |-- SubscriptionPriceDto.ts
    |   |   |   |   |-- SubscriptionProductDto.ts
    |   |   |   |-- tenants
    |   |   |   |   |-- TenantDto.ts
    |   |   |   |   |-- TenantJoinSettingsDto.ts
    |   |   |   |   |-- TenantProductDto.ts
    |   |   |   |   |-- TenantUserDto.ts
    |   |   |   |-- users
    |   |   |   |   |-- UserDto.ts
    |   |   |   |-- workspaces
    |   |   |       |-- WorkspaceDto.ts
    |   |   |       |-- WorkspaceUserDto.ts
    |   |   |-- shared
    |   |       |-- FileBase64.ts
    |   |       |-- Month.ts
    |   |       |-- Months.ts
    |   |-- enums
    |   |   |-- app
    |   |   |   |-- contracts
    |   |   |   |   |-- ContractActivityType.ts
    |   |   |   |   |-- ContractInvitationStatus.ts
    |   |   |   |   |-- ContractMemberRole.ts
    |   |   |   |   |-- ContractStatus.ts
    |   |   |   |-- usages
    |   |   |       |-- AppUsageType.ts
    |   |   |-- core
    |   |   |   |-- links
    |   |   |   |   |-- LinkStatus.ts
    |   |   |   |-- subscriptions
    |   |   |   |   |-- SubscriptionBillingPeriod.ts
    |   |   |   |   |-- SubscriptionPriceType.ts
    |   |   |   |-- tenants
    |   |   |   |   |-- TenantUserJoined.ts
    |   |   |   |   |-- TenantUserRole.ts
    |   |   |   |   |-- TenantUserStatus.ts
    |   |   |   |   |-- WorkspaceType.ts
    |   |   |   |-- users
    |   |   |       |-- UserLoginType.ts
    |   |   |       |-- UserType.ts
    |   |   |-- shared
    |   |       |-- ApplicationLayout.ts
    |   |       |-- Colors.ts
    |   |       |-- Periodicity.ts
    |   |       |-- Role.ts
    |   |       |-- SvgIcon.ts
    |   |       |-- Theme.ts
    |   |-- pricing
    |   |   |-- plans.ts
    |   |-- sidebar
    |       |-- AdminSidebar.ts
    |       |-- AppSidebar.ts
    |       |-- SidebarGroup.ts
    |       |-- SidebarItem.ts
    |-- assets
    |   |-- css
    |   |   |-- index.css
    |   |-- icons
    |   |   |-- IconContract.{jsx,vue,svelte}
    |   |   |-- IconContractArchived.{jsx,vue,svelte}
    |   |   |-- IconContractCheck.{jsx,vue,svelte}
    |   |   |-- IconContractClock.{jsx,vue,svelte}
    |   |   |-- IconEmptyResults.{jsx,vue,svelte}
    |   |   |-- IconSign.{jsx,vue,svelte}
    |   |   |-- IconWorkers.{jsx,vue,svelte}
    |   |-- img
    |       |-- icon-dark.png
    |       |-- icon-light.png
    |       |-- logo-dark.png
    |       |-- logo-light.png
    |-- components
    |   |-- app
    |   |   |-- AppLayout.{tsx,vue,svelte}
    |   |   |-- contracts
    |   |   |   |-- ContractActivity.{tsx,vue,svelte}
    |   |   |   |-- ContractDetails.{tsx,vue,svelte}
    |   |   |   |-- ContractEmployees.{tsx,vue,svelte}
    |   |   |   |-- ContractMembers.{tsx,vue,svelte}
    |   |   |   |-- ContractsList.{tsx,vue,svelte}
    |   |   |   |-- ContractsListAndTable.{tsx,vue,svelte}
    |   |   |   |-- SelectContractMembers.{tsx,vue,svelte}
    |   |   |-- employees
    |   |   |   |-- AddEmployees.{tsx,vue,svelte}
    |   |   |   |-- EmployeeProfile.{tsx,vue,svelte}
    |   |   |   |-- EmployeesList.{tsx,vue,svelte}
    |   |   |   |-- EmployeesListAndTable.{tsx,vue,svelte}
    |   |   |   |-- SelectEmployees.{tsx,vue,svelte}
    |   |   |-- links
    |   |   |   |-- all
    |   |   |   |   |-- AllLinksList.{tsx,vue,svelte}
    |   |   |   |   |-- AllLinksListAndTable.{tsx,vue,svelte}
    |   |   |   |   |-- LinkProfile.{tsx,vue,svelte}
    |   |   |   |-- clients
    |   |   |   |   |-- ClientsList.{tsx,vue,svelte}
    |   |   |   |   |-- ClientsListAndTable.{tsx,vue,svelte}
    |   |   |   |-- pending
    |   |   |   |   |-- NewLink.{tsx,vue,svelte}
    |   |   |   |   |-- PendingLinksList.{tsx,vue,svelte}
    |   |   |   |-- providers
    |   |   |   |   |-- ProvidersList.{tsx,vue,svelte}
    |   |   |   |   |-- ProvidersListAndTable.{tsx,vue,svelte}
    |   |   |   |-- selectors
    |   |   |       |-- LinkSelector.{tsx,vue,svelte}
    |   |   |-- usages
    |   |       |-- ClientsUsage.{tsx,vue,svelte}
    |   |       |-- EmployeesUsage.{tsx,vue,svelte}
    |   |       |-- ProvidersUsage.{tsx,vue,svelte}
    |   |-- core
    |   |   |-- settings
    |   |   |   |-- members
    |   |   |   |   |-- EditMember.{tsx,vue,svelte}
    |   |   |   |   |-- MembersListAndTable.{tsx,vue,svelte}
    |   |   |   |   |-- NewMember.{tsx,vue,svelte}
    |   |   |   |-- subscription
    |   |   |   |   |-- MySubscription.{tsx,vue,svelte}
    |   |   |   |   |-- MySubscriptionPaymentDetails.{tsx,vue,svelte}
    |   |   |   |   |-- MySubscriptionPlan.{tsx,vue,svelte}
    |   |   |   |   |-- MySubscriptionProducts.{tsx,vue,svelte}
    |   |   |   |-- tenant
    |   |   |       |-- TenantNew.{tsx,vue,svelte}
    |   |   |-- tenants
    |   |   |   |-- TenantProfile.{tsx,vue,svelte}
    |   |   |   |-- TenantSubscription.{tsx,vue,svelte}
    |   |   |-- users
    |   |   |   |-- SelectUsers.{tsx,vue,svelte}
    |   |   |-- workspaces
    |   |       |-- EditWorkspace.{tsx,vue,svelte}
    |   |       |-- NewWorkspace.{tsx,vue,svelte}
    |   |       |-- SelectWorkspaces.{tsx,vue,svelte}
    |   |       |-- WorkspacesListAndTable.{tsx,vue,svelte}
    |   |-- front
    |   |   |-- Faq.{tsx,vue,svelte}
    |   |   |-- Features.{tsx,vue,svelte}
    |   |   |-- Footer.{tsx,vue,svelte}
    |   |   |-- Header.{tsx,vue,svelte}
    |   |   |-- Hero.{tsx,vue,svelte}
    |   |   |-- Icon.{tsx,vue,svelte}
    |   |   |-- JoinNow.{tsx,vue,svelte}
    |   |   |-- Logo.{tsx,vue,svelte}
    |   |   |-- PayCard.{tsx,vue,svelte}
    |   |   |-- Plans.{tsx,vue,svelte}
    |   |-- layouts
    |   |   |-- SidebarLayout.{tsx,vue,svelte}
    |   |   |-- SidebarMenu.{tsx,vue,svelte}
    |   |   |-- StackedLayout.{tsx,vue,svelte}
    |   |   |-- buttons
    |   |   |   |-- ChatSupportButton.{tsx,vue,svelte}
    |   |   |   |-- PendingInvitationsButton.{tsx,vue,svelte}
    |   |   |   |-- ProfileButton.{tsx,vue,svelte}
    |   |   |   |-- QuickActionsButton.{tsx,vue,svelte}
    |   |   |-- icons
    |   |   |   |-- IconAdmin.{jsx,vue,svelte}
    |   |   |   |-- IconApp.{jsx,vue,svelte}
    |   |   |   |-- IconClients.{jsx,vue,svelte}
    |   |   |   |-- IconComponents.{jsx,vue,svelte}
    |   |   |   |-- IconContracts.{jsx,vue,svelte}
    |   |   |   |-- IconDashboard.{jsx,vue,svelte}
    |   |   |   |-- IconEmails.{jsx,vue,svelte}
    |   |   |   |-- IconEmployees.{jsx,vue,svelte}
    |   |   |   |-- IconLinks.{jsx,vue,svelte}
    |   |   |   |-- IconNavigation.{jsx,vue,svelte}
    |   |   |   |-- IconPricing.{jsx,vue,svelte}
    |   |   |   |-- IconProviders.{jsx,vue,svelte}
    |   |   |   |-- IconSettings.{jsx,vue,svelte}
    |   |   |   |-- IconTenants.{jsx,vue,svelte}
    |   |   |   |-- IconUsers.{jsx,vue,svelte}
    |   |   |   |-- SidebarIcon.{tsx,vue,svelte}
    |   |   |-- selectors
    |   |       |-- TenantSelector.{tsx,vue,svelte}
    |   |       |-- WorkspaceSelector.{tsx,vue,svelte}
    |   |-- ui
    |       |-- AllComponentsList.{tsx,vue,svelte}
    |       |-- banners
    |       |   |-- InfoBanner.{tsx,vue,svelte}
    |       |   |-- TopBanner.{tsx,vue,svelte}
    |       |   |-- WarningBanner.{tsx,vue,svelte}
    |       |-- breadcrumbs
    |       |   |-- Breadcrumb.{tsx,vue,svelte}
    |       |-- buttons
    |       |   |-- ButtonPrimary.{tsx,vue,svelte}
    |       |   |-- ButtonSecondary.{tsx,vue,svelte}
    |       |   |-- ButtonTertiary.{tsx,vue,svelte}
    |       |   |-- LoadingButton.{tsx,vue,svelte}
    |       |-- dropdowns
    |       |   |-- Dropdown.{tsx,vue,svelte}
    |       |   |-- DropdownWithClick.{tsx,vue,svelte}
    |       |-- emptyState
    |       |   |-- EmptyState.{tsx,vue,svelte}
    |       |-- loaders
    |       |   |-- Loading.{tsx,vue,svelte}
    |       |-- modals
    |       |   |-- ConfirmModal.{tsx,vue,svelte}
    |       |   |-- ErrorModal.{tsx,vue,svelte}
    |       |   |-- Modal.{tsx,vue,svelte}
    |       |   |-- SuccessModal.{tsx,vue,svelte}
    |       |-- radios
    |       |   |-- PlansRadioButtons.{tsx,vue,svelte}
    |       |-- selectors
    |       |   |-- LayoutSelector.{tsx,vue,svelte}
    |       |   |-- LocaleSelector.{tsx,vue,svelte}
    |       |-- slideOvers
    |       |   |-- SlideOver.{tsx,vue,svelte}
    |       |-- tabs
    |       |   |-- Tabs.{tsx,vue,svelte}
    |       |-- toggles
    |       |   |-- BillingPeriodToggle.{tsx,vue,svelte}
    |       |   |-- CurrencyToggle.{tsx,vue,svelte}
    |       |   |-- DarkModeToggle.{tsx,vue,svelte}
    |       |-- uploaders
    |           |-- PdfViewer.{tsx,vue,svelte}
    |           |-- UploadDocument.{tsx,vue,svelte}
    |           |-- UploadImage.{tsx,vue,svelte}
    |-- locale
    |   |-- en-US.json
    |   |-- es-MX.json
    |   |-- i18n.ts
    |   |-- supportedLocales.ts
    |-- plugins
    |   |-- axiosMiddleware.ts
    |   |-- logging.ts
    |   |-- tinyEventBus.ts
    |-- router
    |   |-- PrivateRoute.{tsx,vue,svelte}
    |   |-- ScrollToTop.{tsx,vue,svelte}
    |-- services
    |   |-- index.ts
    |   |-- api
    |       |-- ApiService.ts
    |       |-- app
    |       |   |-- contracts
    |       |   |   |-- ContractService.ts
    |       |   |   |-- FakeContractService.ts
    |       |   |   |-- FakePdfBase64.ts
    |       |   |   |-- FakeXmlBase64.ts
    |       |   |   |-- IContractService.ts
    |       |   |-- employees
    |       |   |   |-- EmployeeService.ts
    |       |   |   |-- FakeEmployeeService.ts
    |       |   |   |-- IEmployeeService.ts
    |       |   |-- templateService
    |       |       |-- FakeTemplateService.ts
    |       |       |-- ITemplateService.ts
    |       |       |-- TemplateService.ts
    |       |-- core
    |           |-- links
    |           |   |-- FakeCompanies.ts
    |           |   |-- FakeLinkService.ts
    |           |   |-- ILinkService.ts
    |           |   |-- LinkService.ts
    |           |-- setup
    |           |   |-- FakeSetupService.ts
    |           |   |-- ISetupService.ts
    |           |   |-- SetupService.ts
    |           |-- subscriptions
    |           |   |-- FakeSubscriptionManagerService.ts
    |           |   |-- FakeSubscriptionProductService.ts
    |           |   |-- ISubscriptionManagerService.ts
    |           |   |-- ISubscriptionProductService.ts
    |           |   |-- SubscriptionManagerService.ts
    |           |   |-- SubscriptionProductService.ts
    |           |-- tenants
    |           |   |-- FakeNamesAndEmails.ts
    |           |   |-- FakeTenantService.ts
    |           |   |-- FakeTenantUserInvitationService.ts
    |           |   |-- FakeTenantUsersService.ts
    |           |   |-- ITenantService.ts
    |           |   |-- ITenantUserInvitationService.ts
    |           |   |-- ITenantUsersService.ts
    |           |   |-- TenantService.ts
    |           |   |-- TenantUserInvitationService.ts
    |           |   |-- TenantUsersService.ts
    |           |-- users
    |           |   |-- AuthenticationService.ts
    |           |   |-- FakeAuthenticationService.ts
    |           |   |-- FakeUserService.ts
    |           |   |-- IAuthenticationService.ts
    |           |   |-- IUserService.ts
    |           |   |-- UserService.ts
    |           |-- workspaces
    |               |-- FakeWorkspaceService.ts
    |               |-- IWorkspaceService.ts
    |               |-- WorkspaceService.ts
    |-- store
    |   |-- index.ts
    |   |-- localStorage.ts
    |   |-- types.ts
    |   |-- modules
    |       |-- accountReducer.ts
    |       |-- appReducer.ts
    |       |-- authReducer.ts
    |       |-- pricingReducer.ts
    |       |-- tenantReducer.ts
    |       |-- themeReducer.ts
    |-- utils
    |   |-- shared
    |   |   |-- ClassesUtils.ts
    |   |   |-- ColorUtils.ts
    |   |   |-- DateUtils.ts
    |   |   |-- KeypressUtils.ts
    |   |   |-- NumberUtils.ts
    |   |   |-- ObjectUtils.ts
    |   |   |-- TimezonesUtils.ts
    |   |-- store
    |       |-- PricingUtils.ts
    |       |-- UserUtils.ts
    |-- views
        |-- admin
        |   |-- Components.{tsx,vue,svelte}
        |   |-- Emails.{tsx,vue,svelte}
        |   |-- Index.{tsx,vue,svelte}
        |   |-- Navigation.{tsx,vue,svelte}
        |   |-- Pricing.{tsx,vue,svelte}
        |   |-- Users.{tsx,vue,svelte}
        |   |-- tenants
        |       |-- Index.{tsx,vue,svelte}
        |       |-- Tenant.{tsx,vue,svelte}
        |-- app
        |   |-- contracts
        |   |   |-- Contract.{tsx,vue,svelte}
        |   |   |-- Index.{tsx,vue,svelte}
        |   |   |-- NewContract.{tsx,vue,svelte}
        |   |-- employees
        |       |-- Employee.{tsx,vue,svelte}
        |       |-- Index.{tsx,vue,svelte}
        |       |-- NewEmployees.{tsx,vue,svelte}
        |-- core
        |   |-- Dashboard.{tsx,vue,svelte}
        |   |-- Index.{tsx,vue,svelte}
        |   |-- Unauthorized.{tsx,vue,svelte}
        |   |-- links
        |   |   |-- Index.{tsx,vue,svelte}
        |   |   |-- Link.{tsx,vue,svelte}
        |   |-- settings
        |       |-- Index.{tsx,vue,svelte}
        |       |-- Members.{tsx,vue,svelte}
        |       |-- Profile.{tsx,vue,svelte}
        |       |-- Tenant.{tsx,vue,svelte}
        |       |-- Workspaces.{tsx,vue,svelte}
        |-- front
            |-- Components.{tsx,vue,svelte}
            |-- Contact.{tsx,vue,svelte}
            |-- Landing.{tsx,vue,svelte}
            |-- Pricing.{tsx,vue,svelte}
            |-- PrivacyPolicy.{tsx,vue,svelte}
            |-- TermsAndConditions.{tsx,vue,svelte}
            |-- account
                |-- Forgot.{tsx,vue,svelte}
                |-- Invitation.{tsx,vue,svelte}
                |-- JoinTenant.{tsx,vue,svelte}
                |-- Login.{tsx,vue,svelte}
                |-- Register.{tsx,vue,svelte}
                |-- Reset.{tsx,vue,svelte}
                |-- Verify.{tsx,vue,svelte}