From f995e1864cc607b21781bda04ac1c40cfade2a4f Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Mon, 13 Apr 2026 12:07:39 +0300 Subject: [PATCH] add shared link qr code --- .../templates_share_link_qr_controller.rb | 22 ++ app/views/icons/_printer.html.erb | 6 + app/views/icons/_qrcode.html.erb | 15 + app/views/templates_share_link/show.html.erb | 7 +- .../_branding.html.erb | 2 + .../templates_share_link_qr/_logo.html.erb | 2 + .../templates_share_link_qr/disabled.html.erb | 10 + .../templates_share_link_qr/show.html.erb | 288 ++++++++++++++++++ config/locales/i18n.yml | 21 ++ config/routes.rb | 1 + 10 files changed, 373 insertions(+), 1 deletion(-) create mode 100644 app/controllers/templates_share_link_qr_controller.rb create mode 100644 app/views/icons/_printer.html.erb create mode 100644 app/views/icons/_qrcode.html.erb create mode 100644 app/views/templates_share_link_qr/_branding.html.erb create mode 100644 app/views/templates_share_link_qr/_logo.html.erb create mode 100644 app/views/templates_share_link_qr/disabled.html.erb create mode 100644 app/views/templates_share_link_qr/show.html.erb diff --git a/app/controllers/templates_share_link_qr_controller.rb b/app/controllers/templates_share_link_qr_controller.rb new file mode 100644 index 00000000..e16c0eec --- /dev/null +++ b/app/controllers/templates_share_link_qr_controller.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class TemplatesShareLinkQrController < ApplicationController + load_and_authorize_resource :template + + def show + return render :disabled, layout: 'plain' unless @template.shared_link? + + shared_link_url = start_form_url(slug: @template.slug, host: form_link_host) + + @qr_svg_code = RQRCode::QRCode.new(shared_link_url, level: :m).as_svg(viewbox: true) + + @page_size = + if TimeUtils.timezone_abbr(current_account.timezone, Time.current.beginning_of_year).in?(TimeUtils::US_TIMEZONES) + 'Letter' + else + 'A4' + end + + render :show, layout: false + end +end diff --git a/app/views/icons/_printer.html.erb b/app/views/icons/_printer.html.erb new file mode 100644 index 00000000..feacbdbb --- /dev/null +++ b/app/views/icons/_printer.html.erb @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/views/icons/_qrcode.html.erb b/app/views/icons/_qrcode.html.erb new file mode 100644 index 00000000..43457966 --- /dev/null +++ b/app/views/icons/_qrcode.html.erb @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/app/views/templates_share_link/show.html.erb b/app/views/templates_share_link/show.html.erb index b654c8d7..910559b4 100644 --- a/app/views/templates_share_link/show.html.erb +++ b/app/views/templates_share_link/show.html.erb @@ -23,7 +23,12 @@ <% end %>
- + <%= render 'shared/clipboard_copy', icon: 'copy', text: start_form_url(slug: @template.slug, host: form_link_host), class: 'base-button', icon_class: 'w-6 h-6 text-white', copy_title: t('copy'), copied_title: t('copied') %> diff --git a/app/views/templates_share_link_qr/_branding.html.erb b/app/views/templates_share_link_qr/_branding.html.erb new file mode 100644 index 00000000..47822ac5 --- /dev/null +++ b/app/views/templates_share_link_qr/_branding.html.erb @@ -0,0 +1,2 @@ +<%= t('powered_by') %> +<%= Docuseal.product_name %> diff --git a/app/views/templates_share_link_qr/_logo.html.erb b/app/views/templates_share_link_qr/_logo.html.erb new file mode 100644 index 00000000..067e3227 --- /dev/null +++ b/app/views/templates_share_link_qr/_logo.html.erb @@ -0,0 +1,2 @@ +<%= render 'shared/logo' %> +<%= Docuseal.product_name %> diff --git a/app/views/templates_share_link_qr/disabled.html.erb b/app/views/templates_share_link_qr/disabled.html.erb new file mode 100644 index 00000000..79c12aef --- /dev/null +++ b/app/views/templates_share_link_qr/disabled.html.erb @@ -0,0 +1,10 @@ +
+

+ <%= t('share_link_is_currently_disabled') %> +

+ <% if can?(:update, @template) %> + + <%= button_to button_title(title: t('enable_shared_link'), icon: svg_icon('lock_open', class: 'w-6 h-6')), template_share_link_path(@template), params: { template: { shared_link: true }, redir: template_share_link_qr_path(@template) }, method: :post, data: { turbo: false }, class: 'white-button w-full' %> + + <% end %> +
diff --git a/app/views/templates_share_link_qr/show.html.erb b/app/views/templates_share_link_qr/show.html.erb new file mode 100644 index 00000000..62fbd757 --- /dev/null +++ b/app/views/templates_share_link_qr/show.html.erb @@ -0,0 +1,288 @@ + +<% page_width_css = @page_size == 'Letter' ? 8.5 * 96.0 : 210.0 * 96.0 / 25.4 %> +<% page_height_css = @page_size == 'Letter' ? 11.0 * 96.0 : 297.0 * 96.0 / 25.4 %> +<% page_width = @page_size == 'Letter' ? '8.5in' : '210mm' %> +<% page_cqw = ->(px) { format('%.6fcqw', px / page_width_css * 100.0) } %> + + + + + <%= @template.name %> + + + +
+
+ +
+
<%= @template.name %>
+
+ <%== @qr_svg_code %> +
+ +
+
+ <%= render 'branding' %> +
+
+
+ + + + diff --git a/config/locales/i18n.yml b/config/locales/i18n.yml index da006683..3801b210 100644 --- a/config/locales/i18n.yml +++ b/config/locales/i18n.yml @@ -367,6 +367,9 @@ en: &en sign_out: Sign out page_number: 'Page %{number}' powered_by: Powered by + qr_code: QR Code + print: Print + scan_the_qr_code_above_with_your_phone_camera_to_open_and_sign_this_document: Scan the QR code above with your phone camera to open and sign this document. count_documents_signed_with_html: '%{count} documents signed with' storage: Storage notifications: Notifications @@ -1406,6 +1409,9 @@ es: &es sign_out: Cerrar sesión page_number: 'Página %{number}' powered_by: Desarrollado por + qr_code: Código QR + print: Imprimir + scan_the_qr_code_above_with_your_phone_camera_to_open_and_sign_this_document: Escanea el código QR de arriba con la cámara de tu teléfono para abrir y firmar este documento. count_documents_signed_with_html: '%{count} documentos firmados con' storage: Almacenamiento notifications: Notificaciones @@ -2442,6 +2448,9 @@ it: &it sign_out: Esci page_number: 'Pagina %{number}' powered_by: Fornito da + qr_code: Codice QR + print: Stampa + scan_the_qr_code_above_with_your_phone_camera_to_open_and_sign_this_document: Scansiona il codice QR qui sopra con la fotocamera del tuo telefono per aprire e firmare questo documento. count_documents_signed_with_html: '%{count} documenti firmati con' storage: Archiviazione notifications: Notifiche @@ -3479,6 +3488,9 @@ fr: &fr sign_out: Se déconnecter page_number: Page %{number} powered_by: Propulsé par + qr_code: Code QR + print: Imprimer + scan_the_qr_code_above_with_your_phone_camera_to_open_and_sign_this_document: Scannez le code QR ci-dessus avec l'appareil photo de votre téléphone pour ouvrir et signer ce document. count_documents_signed_with_html: "%{count} documents signés avec" storage: Stockage notifications: Notifications @@ -4512,6 +4524,9 @@ pt: &pt sign_out: Sair page_number: 'Página %{number}' powered_by: Desenvolvido por + qr_code: Código QR + print: Imprimir + scan_the_qr_code_above_with_your_phone_camera_to_open_and_sign_this_document: Escaneie o código QR acima com a câmera do seu telefone para abrir e assinar este documento. count_documents_signed_with_html: '%{count} documentos assinados com' storage: Armazenamento notifications: Notificações @@ -5548,6 +5563,9 @@ de: &de sign_out: Abmelden page_number: 'Seite %{number}' powered_by: Bereitgestellt von + qr_code: QR-Code + print: Drucken + scan_the_qr_code_above_with_your_phone_camera_to_open_and_sign_this_document: Scannen Sie den QR-Code oben mit Ihrer Handykamera, um dieses Dokument zu öffnen und zu unterzeichnen. count_documents_signed_with_html: '%{count} Dokumente signiert mit' storage: Speicher notifications: Benachrichtigungen @@ -6985,6 +7003,9 @@ nl: &nl sign_out: Afmelden page_number: Pagina %{number} powered_by: Aangedreven door + qr_code: QR-code + print: Afdrukken + scan_the_qr_code_above_with_your_phone_camera_to_open_and_sign_this_document: Scan de bovenstaande QR-code met je telefooncamera om dit document te openen en te ondertekenen. count_documents_signed_with_html: "%{count} documenten ondertekend met" storage: Opslag notifications: Meldingen diff --git a/config/routes.rb b/config/routes.rb index f9d3ae38..fc13ceaa 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -108,6 +108,7 @@ Rails.application.routes.draw do resource :code_modal, only: %i[show], controller: 'templates_code_modal' resource :preferences, only: %i[show create destroy], controller: 'templates_preferences' resource :share_link, only: %i[show create], controller: 'templates_share_link' + resource :share_link_qr, only: %i[show], controller: 'templates_share_link_qr' resources :recipients, only: %i[create], controller: 'templates_recipients' resources :prefillable_fields, only: %i[create], controller: 'templates_prefillable_fields' resources :submissions_export, only: %i[index new]