{t("Account Settings")}

{t("Manage your account email address, password, and security settings")}

<%= if @active_tab == "personal" do %>

{t("Personal Information")}

{t("Update your name and timezone preferences.")}

<.form for={@profile_form} phx-submit="update_profile" id="update_profile" class="md:col-span-2" >

{t( "Choose which organization you see by default when logging in or navigating to pages without an organization context." )}

<% end %> <%= if @active_tab == "account" do %>

{t("Email Address")}

{t( "Update your email address. You'll receive a confirmation link to verify the new address." )}

<.form for={@email_form} phx-submit="update_email" id="update_email" class="md:col-span-2" >

{t("Change Password")}

{t( "Update your password. You'll be logged out and need to sign in again with your new password." )}

<.form for={@password_form} phx-submit="update_password" id="update_password" class="md:col-span-2" >
<%= if @password_breach_count && @password_breach_count > 0 do %>
<.icon name="hero-exclamation-triangle" class="h-5 w-5 text-yellow-400" />

{t("Password found in data breaches")}

This password has appeared {@password_breach_count} {if @password_breach_count == 1, do: "time", else: "times"} in known data breaches. We strongly recommend choosing a different, more unique password to protect your account.

<% end %>
<% end %> <%= if @active_tab == "api" do %>

{t("API Tokens")}

{t( "Create API tokens to access Towerops programmatically. Tokens are scoped to a specific organization." )}

<%= if Enum.empty?(@api_tokens) do %>
<.icon name="hero-code-bracket" class="mx-auto h-12 w-12 text-gray-400" />

{t("No API tokens")}

{t("Get started by creating a new API token.")}

<% else %>
    <%= for token <- @api_tokens do %>
  • {token.name}

    {token.organization.name}

    <%= if token.last_used_at do %> Last used {ToweropsWeb.TimeHelpers.format_date( token.last_used_at, @current_scope.timezone )} <% else %> {t("Never used")} <% end %>

  • <% end %>
<% end %>
<% end %> <%= if @active_tab == "notifications" do %>

{t("Mobile Devices")}

{t("Manage mobile devices that receive push notifications for alerts.")}

<%= if Enum.empty?(@mobile_sessions) do %>
<.icon name="hero-device-phone-mobile" class="mx-auto h-12 w-12 text-gray-400" />

{t("No mobile devices")}

{t("Add a mobile device to receive push notifications for alerts.")}

<.link navigate={~p"/mobile/qr-login"} class="inline-flex items-center gap-x-1.5 rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-xs hover:bg-indigo-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 dark:bg-indigo-500 dark:hover:bg-indigo-400" > <.icon name="hero-qr-code" class="-ml-0.5 h-5 w-5" /> Add Device
<% else %>
    <%= for session <- @mobile_sessions do %>
  • {session.device_name || "Unknown Device"}

    <%= if session.alerts_enabled do %> <.icon name="hero-bell" class="h-3 w-3" /> Alerts On <% else %> <.icon name="hero-bell-slash" class="h-3 w-3" /> Alerts Off <% end %>

    {session.device_os} • {session.app_version}

    Last used {ToweropsWeb.TimeHelpers.format_date( session.last_used_at, @current_scope.timezone )}

  • <% end %>
<.link navigate={~p"/mobile/qr-login"} class="inline-flex items-center gap-x-1.5 rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-xs hover:bg-indigo-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 dark:bg-indigo-500 dark:hover:bg-indigo-400" > <.icon name="hero-qr-code" class="-ml-0.5 h-5 w-5" /> Add Device
<% end %>
<% end %> <%= if @active_tab == "sessions" do %> <%= if @show_security_alert do %>
<.icon name="hero-exclamation-triangle" class="h-5 w-5 text-amber-400" />

{t("Security Alert")}

We detected {@failed_login_count} failed login attempts in the last 24 hours. {t( "Please review your login history below and ensure all activity is authorized." )}

<% end %>

{t("Active Sessions")}

{t("Manage browser sessions where you're currently logged in.")}

<%= if Enum.empty?(@browser_sessions) do %>
<.icon name="hero-computer-desktop" class="mx-auto h-12 w-12 text-gray-400" />

{t("No active sessions")}

{t("Your current session will appear here after your next login.")}

<% else %>
    <%= for session <- @browser_sessions do %> <% is_current = current_session?(session, get_current_token_id(assigns)) %>
  • <%= if String.contains?(String.downcase(session.user_agent || ""), ["mobile", "android", "iphone", "ipad"]) do %> <.icon name="hero-device-phone-mobile" class="h-6 w-6 text-gray-400" /> <% else %> <.icon name="hero-computer-desktop" class="h-6 w-6 text-gray-400" /> <% end %>

    {format_browser_info(session)}

    <%= if is_current do %> {t("Current Session")} <% end %>
    <.icon name="hero-map-pin" class="h-3 w-3" /> {format_location(session)} {session.ip_address}
    <.icon name="hero-clock" class="h-3 w-3" /> Last active {format_relative_time(session.last_activity_at)}
  • <% end %>
<%= if length(@browser_sessions) > 1 do %>
<% end %> <% end %>

{t("Login History")}

{t("Recent login attempts to your account, including successful and failed attempts.")}

<%= if Enum.empty?(@login_history) do %>
<.icon name="hero-clock" class="mx-auto h-12 w-12 text-gray-400" />

{t("No login history")}

{t("Your login attempts will appear here.")}

<% else %>
<%= for attempt <- @login_history do %> <% end %>
{t("Date & Time")} {t("Status")} {t("Method")} {t("Location")} {t("IP Address")}
{format_timestamp_in_timezone( attempt.inserted_at, @current_scope.timezone, @current_scope.time_format )} <%= if attempt.success do %> <.icon name="hero-check-circle" class="h-3 w-3" /> Success <% else %> <.icon name="hero-x-circle" class="h-3 w-3" /> Failed <% end %> <% {icon, text} = login_method_info(attempt.method) %> <.icon name={icon} class="h-3 w-3" /> {text} {format_location(attempt)} {attempt.ip_address}
<%= if @login_history_pagination.total_pages > 1 do %>
<.link :if={@login_history_pagination.page > 1} patch={ ~p"/users/settings?tab=#{@active_tab}&page=#{@login_history_pagination.page - 1}" } class="relative inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 dark:border-white/10 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700" > {t("Previous")} <.link :if={@login_history_pagination.page < @login_history_pagination.total_pages} patch={ ~p"/users/settings?tab=#{@active_tab}&page=#{@login_history_pagination.page + 1}" } class="relative ml-3 inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 dark:border-white/10 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700" > {t("Next")}
<% end %> <% end %>
<% end %> <%= if @active_tab == "security" do %>

{t("Authenticator Apps")}

{t( "Manage TOTP devices for two-factor authentication. You must have at least one device configured." )}

<%= if Enum.empty?(@totp_devices) do %>
<.icon name="hero-device-phone-mobile" class="mx-auto h-12 w-12 text-gray-400" />

{t("No authenticator apps")}

{t("Add your first authenticator app to enable two-factor authentication.")}

<% else %>
    <%= for device <- @totp_devices do %>
  • {device.name}

    Added {ToweropsWeb.TimeHelpers.format_date( device.inserted_at, @current_scope.timezone )}

    <%= if device.last_used_at do %>

    Last used {format_relative_time(device.last_used_at)}

    <% end %>
  • <% end %>
<% end %>

{t("Recovery Codes")}

{t("Single-use backup codes for account access if you lose your authenticator app.")}

{t("Available Recovery Codes")}

<%= if @unused_recovery_codes_count == 0 do %> {t("No recovery codes available")} - Generate new codes immediately <% else %> {t("You have")} {@unused_recovery_codes_count} unused recovery code{if @unused_recovery_codes_count != 1, do: "s"} <% end %>

<%= if @unused_recovery_codes_count == 0 do %>
<.icon name="hero-exclamation-triangle" class="h-5 w-5 text-amber-400" />

{t("No Recovery Codes")}

{t( "You have no recovery codes available. If you lose access to your authenticator app," )} you won't be able to log in. Generate new codes now.

<% end %>
<% end %>
<%= if @show_revoke_all_modal do %> <% end %> <%= if @show_add_token_modal do %> <% end %> <%= if @show_token_modal && @created_token do %> <% end %> <%= if @show_add_device_modal do %> <% end %> <%= if @show_device_qr_modal && @new_device_qr_code do %> <% end %> <%= if @show_recovery_codes_modal && @generated_recovery_codes do %> <% end %>