mirror of
https://github.com/we-promise/sure.git
synced 2026-05-25 21:44:56 +00:00
* add missing Hungarian translations for newly extracted strings Replace hard-coded UI strings with I18n lookups across controllers, models and views (breadcrumbs, dashboard, reports, settings, transactions, balance sheet, MFA status). Update models to use translations for category defaults, account/display names, classification group and period labels; remove a few hardcoded display_name methods. Add and update numerous locale files (English and extensive Hungarian translations, plus model/view/doorkeeper entries) to provide the required keys. These changes centralize copy for localization and prepare the app for Hungarian/English UI text. * Pluralize account type labels; tidy Crypto model Update English locale account type labels to use plural forms for consistency (Investment(s), Properties, Vehicles, Other Assets, Credit Cards, Loans, Other Liabilities). Also remove an extra blank line in app/models/crypto.rb to tidy up formatting. * Back to singular * fix(i18n): separate singular and group account labels * Update _accountable_group.html.erb * Use I18n plural names for account types Change Accountable#display_name to look up pluralized account type names via I18n (accounts.types_plural.<underscored_class>) with a fallback to the legacy display logic. Add legacy_display_name helper to preserve previous behavior (singular for Depository and Crypto, pluralized otherwise). Add corresponding types_plural entries in English and Hungarian locale files for various account types. --------- Co-authored-by: Juan José Mata <jjmata@jjmata.com> Co-authored-by: sure-admin <sure-admin@splashblot.com>
179 lines
7.7 KiB
Plaintext
179 lines
7.7 KiB
Plaintext
<%= content_for :page_title, t(".page_title") %>
|
|
|
|
<%= settings_section title: t(".mfa_title"), subtitle: t(".mfa_description") do %>
|
|
<div class="space-y-4">
|
|
<div class="p-3 shadow-border-xs bg-container rounded-lg md:flex md:justify-between md:items-center">
|
|
<div class="flex items-center gap-3">
|
|
<div class="w-9 h-9 rounded-full bg-surface-inset flex justify-center items-center">
|
|
<%= icon "shield-check" %>
|
|
</div>
|
|
|
|
<div class="text-sm space-y-1">
|
|
<% if Current.user.otp_required? %>
|
|
<p class="text-primary"><%= t(".mfa_enabled_status_html") %></p>
|
|
<p class="text-secondary"><%= t(".mfa_enabled_description") %></p>
|
|
<% else %>
|
|
<p class="text-primary"><%= t(".mfa_disabled_status_html") %></p>
|
|
<p class="text-secondary"><%= t(".mfa_disabled_description") %></p>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-4 md:mt-0">
|
|
<% if Current.user.otp_required? %>
|
|
<%= render DS::Button.new(
|
|
text: t(".disable_mfa"),
|
|
variant: "secondary",
|
|
href: disable_mfa_path,
|
|
method: :delete,
|
|
confirm: CustomConfirm.new(
|
|
title: t(".disable_mfa_confirm"),
|
|
body: t(".disable_mfa_confirm"),
|
|
btn_text: t(".disable_mfa"),
|
|
destructive: true
|
|
)
|
|
) %>
|
|
<% else %>
|
|
<%= render DS::Link.new(
|
|
text: t(".enable_mfa"),
|
|
variant: "primary",
|
|
href: new_mfa_path
|
|
) %>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
|
|
<% if Current.user.otp_required? %>
|
|
<%= settings_section title: t(".webauthn_title"), subtitle: t(".webauthn_description") do %>
|
|
<div class="space-y-4">
|
|
<% if @webauthn_credentials.any? %>
|
|
<div class="space-y-2">
|
|
<% @webauthn_credentials.each do |credential| %>
|
|
<div class="flex items-center justify-between bg-container p-4 shadow-border-xs rounded-lg">
|
|
<div class="flex items-center gap-3">
|
|
<div class="w-9 h-9 shrink-0 bg-surface rounded-full flex items-center justify-center">
|
|
<%= icon "fingerprint", class: "w-5 h-5 text-secondary" %>
|
|
</div>
|
|
<div>
|
|
<p class="font-medium text-primary"><%= credential.nickname %></p>
|
|
<p class="text-sm text-secondary">
|
|
<%= t(".webauthn_added", date: l(credential.created_at.to_date)) %>
|
|
<% if credential.last_used_at.present? %>
|
|
<span><%= t(".webauthn_last_used", time_ago: time_ago_in_words(credential.last_used_at)) %></span>
|
|
<% end %>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<%= render DS::Button.new(
|
|
text: t(".webauthn_remove"),
|
|
variant: "outline_destructive",
|
|
size: "sm",
|
|
href: settings_webauthn_credential_path(credential),
|
|
method: :delete,
|
|
confirm: CustomConfirm.new(
|
|
title: t(".webauthn_remove_confirm"),
|
|
body: t(".webauthn_remove_confirm_body"),
|
|
btn_text: t(".webauthn_remove"),
|
|
destructive: true
|
|
)
|
|
) %>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
<% else %>
|
|
<div class="bg-surface-inset rounded-lg p-4">
|
|
<p class="text-sm text-secondary"><%= t(".webauthn_empty") %></p>
|
|
</div>
|
|
<% end %>
|
|
|
|
<%= styled_form_with scope: :webauthn_credential,
|
|
url: settings_webauthn_credentials_path,
|
|
method: :post,
|
|
class: "space-y-3",
|
|
data: {
|
|
controller: "webauthn-registration",
|
|
action: "submit->webauthn-registration#register",
|
|
webauthn_registration_options_url_value: options_settings_webauthn_credentials_path,
|
|
webauthn_registration_create_url_value: settings_webauthn_credentials_path,
|
|
webauthn_registration_unsupported_message_value: t(".webauthn_unsupported"),
|
|
webauthn_registration_error_fallback_value: t("webauthn_credentials.failure")
|
|
} do |form| %>
|
|
<%= form.text_field :nickname,
|
|
placeholder: t(".webauthn_name_placeholder"),
|
|
label: t(".webauthn_name_label"),
|
|
data: { webauthn_registration_target: "nickname" } %>
|
|
|
|
<p class="text-sm text-destructive" role="alert" aria-live="assertive" aria-atomic="true" aria-hidden="true" hidden data-webauthn-registration-target="error"></p>
|
|
|
|
<div>
|
|
<%= render DS::Button.new(
|
|
text: t(".webauthn_add"),
|
|
variant: "secondary",
|
|
icon: "fingerprint",
|
|
type: "submit"
|
|
) %>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
<% end %>
|
|
<% end %>
|
|
|
|
<% if @oidc_identities.any? || AuthConfig.sso_providers.any? %>
|
|
<%= settings_section title: t(".sso_title"), subtitle: t(".sso_subtitle") do %>
|
|
<% if @oidc_identities.any? %>
|
|
<div class="space-y-2">
|
|
<% @oidc_identities.each do |identity| %>
|
|
<div class="flex items-center justify-between bg-container p-4 shadow-border-xs rounded-lg">
|
|
<div class="flex items-center gap-3">
|
|
<div class="w-9 h-9 shrink-0 bg-surface rounded-full flex items-center justify-center">
|
|
<% icon_name = identity.provider_config&.dig(:icon).presence || "key" %>
|
|
<%= icon icon_name, class: "w-5 h-5 text-secondary" %>
|
|
</div>
|
|
<div>
|
|
<p class="font-medium text-primary"><%= identity.provider_config&.dig(:label) || identity.provider.titleize %></p>
|
|
<p class="text-sm text-secondary"><%= identity.info&.dig("email") || t(".sso_no_email") %></p>
|
|
<p class="text-xs text-secondary">
|
|
<%= t(".sso_last_used") %>:
|
|
<%= identity.last_authenticated_at&.to_fs(:short) || t(".sso_never") %>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<% if @oidc_identities.count > 1 || Current.user.password_digest.present? %>
|
|
<%= render DS::Button.new(
|
|
text: t(".sso_disconnect"),
|
|
variant: "outline",
|
|
size: "sm",
|
|
href: settings_sso_identity_path(identity),
|
|
method: :delete,
|
|
confirm: CustomConfirm.new(
|
|
title: t(".sso_confirm_title"),
|
|
body: t(".sso_confirm_body", provider: identity.provider_config&.dig(:label) || identity.provider.titleize),
|
|
btn_text: t(".sso_confirm_button"),
|
|
destructive: true
|
|
)
|
|
) %>
|
|
<% end %>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
<% if @oidc_identities.count == 1 && Current.user.password_digest.blank? %>
|
|
<div class="mt-4 p-3 bg-amber-50 border border-amber-200 rounded-lg">
|
|
<div class="flex items-start gap-2">
|
|
<%= icon "alert-triangle", class: "w-5 h-5 text-amber-600 shrink-0 mt-0.5" %>
|
|
<p class="text-sm text-amber-800"><%= t(".sso_warning_message") %></p>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
<% else %>
|
|
<div class="text-center py-6">
|
|
<%= icon "link", class: "w-12 h-12 mx-auto text-secondary mb-3" %>
|
|
<p class="text-secondary"><%= t(".sso_no_identities") %></p>
|
|
<p class="text-sm text-secondary mt-2"><%= t(".sso_connect_hint") %></p>
|
|
</div>
|
|
<% end %>
|
|
<% end %>
|
|
<% end %>
|