# Fully Customize Sign In Pages

`polished` comes with the following pre built `shiny` modules to help you quickly add custom sign in pages to your shiny app:

    sign_in_module()
    sign_in_module_2()

`sign_in_module()` is primarily designed to be used for just email/password sign in (i.e. it does not look great when you include social sign in providers like Google and Microsoft).

`sign_in_module_2()` is designed to look a little better with email/password and social sign in providers.

Use the `sign_in_ui_default()` function to style these modules with your brand’s colors and logos. Check out the docs for `?sign_in_ui_default` and see a full example here for more information.

If you require more customization than that offered by the the above functions, you can fully customize your sign in page with the following 2 functions:

    sign_in_js()
    sign_in_check_jwt()

Behind the scenes, the `sign_in_module()` and `sign_in_module_2()` use the `sign_in_js()` and `sign_in_check_jwt()` to build their UI and server functionality. To fully customize your sign in pages, you can create your own shiny module that uses these functions. To create your own fully customized sign in module, include inputs with the following name-spaced ids:

- “sign_in_email”

- “sign_in_password”

- “sign_in_submit”

- “register_email”

- “register_password”

- “register_password_verify”

- “register_submit”

You can create `shiny::textInputs`, `shiny::passwordInput`s, and `shiny::actionButton`s with the above IDs, or you can use the `email_input` and `password_input` functions available with `polished`; As long as the ID of the inputs match up with the above input IDs, then the JavaScript available with `sign_in_js()` and the server logic in `sign_in_check_jwt()` will be able to handle the sign in and registration. See the example below:

NOTE: when passing your custom module UI as the `sign_in_page_ui` argument to the `secure_ui()` function, you must use “sign_in” as the UI module’s ID (as shown in the example below).

    library(shiny)
    library(polished)

    my_custom_sign_in_module_ui <- function(id) {
      ns <- NS(id)

      tagList(
        shinyjs::useShinyjs(),
        # your custom sign in inputs

        div(
          id = ns("sign_in_page"),
          email_input(
            ns("sign_in_email")
          ),
          password_input(
            ns("sign_in_password")
          ),
          actionButton(
            ns("sign_in_submit"),
            "Sign In"
          ),
          actionLink(
            ns("go_to_register"),
            "Not a member? Register!"
          )
        ),

        # your custom registration inputs.  Your inputs
        shinyjs::hidden(
          div(
            id = ns("register_page"),
            password_input(
              ns("register_password")
            ),
            password_input(
              ns("register_password_verify")
            ),
            actionButton(
              ns("register_submit"),
              "Register"
            ),
            actionLink(
              ns("go_to_sign_in"),
              "Already a member? Sign in!"
            )
          )
        ),

        # make sure to call this function somewhere in your sign in page UI.  It loads
        # the JavaScript used in the sign in and registration process.
        sign_in_js(ns)
      )

    }

    my_custom_sign_in_module <- function(input, output, session) {
      ns <- session$ns
      # your custom sign in and registration server logic
      # We provide an example showing the sign in & registration pages separately

      # show the registration inputs & button
      observeEvent(input$go_to_register, {
        shinyjs::hideElement("sign_in_page")
        shinyjs::showElement("register_page")
      })

      # show the sign in inputs & button
      observeEvent(input$go_to_sign_in, {
        shinyjs::hideElement("register_page")
        shinyjs::showElement("sign_in_page")
      })

      jwt <- reactive({
        # optional: include additional authorization checks here
        input$check_jwt
      })

      sign_in_check_jwt(jwt)
    }

    ui <- secure_ui(
      ui = fluidPage(
        h1("I am a Shiny app!")
      ),
      # you must pass "sign_in" sign in to your custom module `id` argument
      # as done below:
      sign_in_page_ui = my_custom_sign_in_module_ui("sign_in")
    )

    server <- secure_server(
      server = function(input, output, session) {},
      custom_sign_in_server = my_custom_sign_in_module
    )

    shinyApp(
      ui,
      server,
      onStart = function() {
        polished_config(
          api_key = "<your polished.tech API key>",
          app_name = "<your app name from polished.tech>"
        )
      }
    )