testimonials 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +8 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +175 -0
  5. data/Rakefile +11 -0
  6. data/app/controllers/testimonials/api/base_controller.rb +30 -0
  7. data/app/controllers/testimonials/api/stats_controller.rb +20 -0
  8. data/app/controllers/testimonials/api/testimonials_controller.rb +41 -0
  9. data/app/controllers/testimonials/application_controller.rb +50 -0
  10. data/app/controllers/testimonials/collection_controller.rb +18 -0
  11. data/app/controllers/testimonials/events_controller.rb +25 -0
  12. data/app/controllers/testimonials/media_controller.rb +48 -0
  13. data/app/controllers/testimonials/nps_controller.rb +71 -0
  14. data/app/controllers/testimonials/nps_responses_controller.rb +25 -0
  15. data/app/controllers/testimonials/testimonials_controller.rb +194 -0
  16. data/app/controllers/testimonials/widgets_controller.rb +36 -0
  17. data/app/helpers/testimonials/widget_helper.rb +83 -0
  18. data/app/models/testimonials/application_record.rb +7 -0
  19. data/app/models/testimonials/nps_response.rb +24 -0
  20. data/app/models/testimonials/prompt_event.rb +60 -0
  21. data/app/models/testimonials/testimonial.rb +53 -0
  22. data/app/views/layouts/testimonials/application.html.erb +118 -0
  23. data/app/views/layouts/testimonials/collection.html.erb +23 -0
  24. data/app/views/testimonials/collection/show.html.erb +12 -0
  25. data/app/views/testimonials/nps_responses/index.html.erb +67 -0
  26. data/app/views/testimonials/testimonials/index.html.erb +108 -0
  27. data/app/views/testimonials/testimonials/show.html.erb +105 -0
  28. data/config/locales/testimonials.ar.yml +101 -0
  29. data/config/locales/testimonials.bg.yml +101 -0
  30. data/config/locales/testimonials.bn.yml +101 -0
  31. data/config/locales/testimonials.de.yml +101 -0
  32. data/config/locales/testimonials.el.yml +101 -0
  33. data/config/locales/testimonials.en.yml +101 -0
  34. data/config/locales/testimonials.es.yml +101 -0
  35. data/config/locales/testimonials.fr.yml +101 -0
  36. data/config/locales/testimonials.hi.yml +101 -0
  37. data/config/locales/testimonials.hr.yml +101 -0
  38. data/config/locales/testimonials.id.yml +101 -0
  39. data/config/locales/testimonials.it.yml +101 -0
  40. data/config/locales/testimonials.ja.yml +101 -0
  41. data/config/locales/testimonials.ko.yml +101 -0
  42. data/config/locales/testimonials.lb.yml +101 -0
  43. data/config/locales/testimonials.nl.yml +101 -0
  44. data/config/locales/testimonials.pl.yml +101 -0
  45. data/config/locales/testimonials.pt.yml +101 -0
  46. data/config/locales/testimonials.ro.yml +101 -0
  47. data/config/locales/testimonials.ru.yml +101 -0
  48. data/config/locales/testimonials.th.yml +101 -0
  49. data/config/locales/testimonials.tr.yml +101 -0
  50. data/config/locales/testimonials.uk.yml +101 -0
  51. data/config/locales/testimonials.ur.yml +101 -0
  52. data/config/locales/testimonials.vi.yml +101 -0
  53. data/config/locales/testimonials.zh-CN.yml +101 -0
  54. data/config/routes.rb +29 -0
  55. data/lib/generators/testimonials/install/install_generator.rb +42 -0
  56. data/lib/generators/testimonials/install/templates/create_testimonials_tables.rb.tt +53 -0
  57. data/lib/generators/testimonials/install/templates/initializer.rb +70 -0
  58. data/lib/testimonials/configuration.rb +129 -0
  59. data/lib/testimonials/dashboard.js +33 -0
  60. data/lib/testimonials/engine.rb +16 -0
  61. data/lib/testimonials/prompt_helper.rb +15 -0
  62. data/lib/testimonials/version.rb +5 -0
  63. data/lib/testimonials/widget.js +1045 -0
  64. data/lib/testimonials/widget.rb +170 -0
  65. data/lib/testimonials.rb +69 -0
  66. metadata +132 -0
@@ -0,0 +1,67 @@
1
+ <h1><%= t('testimonials.dashboard.nps', default: 'NPS') %></h1>
2
+
3
+ <div class="stat-row">
4
+ <div class="stat">
5
+ <b><%= @score.nil? ? '—' : @score %></b>
6
+ <span><%= t('testimonials.dashboard.nps_score', default: 'NPS score') %></span>
7
+ </div>
8
+ <div class="stat">
9
+ <b><%= @promoters %></b>
10
+ <span><%= t('testimonials.dashboard.promoters', default: 'Promoters (9–10)') %></span>
11
+ </div>
12
+ <div class="stat">
13
+ <b><%= @passives %></b>
14
+ <span><%= t('testimonials.dashboard.passives', default: 'Passives (7–8)') %></span>
15
+ </div>
16
+ <div class="stat">
17
+ <b><%= @detractors %></b>
18
+ <span><%= t('testimonials.dashboard.detractors', default: 'Detractors (0–6)') %></span>
19
+ </div>
20
+ </div>
21
+
22
+ <div class="card">
23
+ <% if @responses.any? %>
24
+ <table>
25
+ <thead>
26
+ <tr>
27
+ <th><%= t('testimonials.dashboard.score', default: 'Score') %></th>
28
+ <th><%= t('testimonials.dashboard.comment', default: 'Comment') %></th>
29
+ <th><%= t('testimonials.dashboard.from', default: 'From') %></th>
30
+ <th><%= t('testimonials.dashboard.received', default: 'Received') %></th>
31
+ </tr>
32
+ </thead>
33
+ <tbody>
34
+ <% @responses.each do |response| %>
35
+ <tr>
36
+ <td>
37
+ <span class="badge nps-<%= response.promoter? ? 'promoter' : (response.detractor? ? 'detractor' : 'passive') %>">
38
+ <%= response.score %>
39
+ </span>
40
+ </td>
41
+ <td class="message"><%= response.comment %></td>
42
+ <td>
43
+ <%= response.name.presence || (response.author_id.present? ? "##{response.author_id}" : nil) %>
44
+ <% if response.email.present? %>
45
+ <div class="muted"><%= response.email %></div>
46
+ <% end %>
47
+ </td>
48
+ <td class="muted" title="<%= response.created_at %>">
49
+ <%= time_ago_in_words(response.created_at) %>
50
+ </td>
51
+ </tr>
52
+ <% end %>
53
+ </tbody>
54
+ </table>
55
+ <% else %>
56
+ <div class="empty"><%= t('testimonials.dashboard.empty', default: 'Nothing here yet.') %></div>
57
+ <% end %>
58
+ </div>
59
+
60
+ <div class="pager">
61
+ <% if @page > 1 %>
62
+ <%= link_to t('testimonials.dashboard.newer', default: '← Newer'), nps_responses_path(page: @page - 1) %>
63
+ <% end %>
64
+ <% if @more %>
65
+ <%= link_to t('testimonials.dashboard.older', default: 'Older →'), nps_responses_path(page: @page + 1) %>
66
+ <% end %>
67
+ </div>
@@ -0,0 +1,108 @@
1
+ <h1><%= t('testimonials.dashboard.title', default: 'Testimonials') %></h1>
2
+
3
+ <div class="tabs">
4
+ <% Testimonials::Testimonial::STATUSES.each do |status| %>
5
+ <%= link_to testimonials_path(status: status, kind: @kind, q: @query),
6
+ class: ('active' if status == @status) do %>
7
+ <%= t("testimonials.statuses.#{status}", default: status.humanize) %>
8
+ <span class="count"><%= @counts.fetch(status, 0) %></span>
9
+ <% end %>
10
+ <% end %>
11
+ </div>
12
+
13
+ <form class="filters" method="get">
14
+ <input type="hidden" name="status" value="<%= @status %>">
15
+ <select name="kind" data-autosubmit="true">
16
+ <option value=""><%= t('testimonials.dashboard.all_kinds', default: 'All kinds') %></option>
17
+ <% Testimonials::Testimonial::KINDS.each do |kind| %>
18
+ <option value="<%= kind %>" <%= 'selected' if kind == @kind %>>
19
+ <%= t("testimonials.kinds.#{kind}", default: kind.humanize) %>
20
+ </option>
21
+ <% end %>
22
+ </select>
23
+ <input type="search" name="q" value="<%= @query %>"
24
+ placeholder="<%= t('testimonials.dashboard.search_placeholder', default: 'Search text, name, email…') %>"
25
+ aria-label="<%= t('testimonials.dashboard.search', default: 'Search') %>">
26
+ <button><%= t('testimonials.dashboard.search', default: 'Search') %></button>
27
+ </form>
28
+
29
+ <div class="card">
30
+ <% if @testimonials.any? %>
31
+ <table>
32
+ <thead>
33
+ <tr>
34
+ <th><%= t('testimonials.dashboard.rating', default: 'Rating') %></th>
35
+ <th><%= t('testimonials.dashboard.testimonial', default: 'Testimonial') %></th>
36
+ <th><%= t('testimonials.dashboard.from', default: 'From') %></th>
37
+ <th><%= t('testimonials.dashboard.consent', default: 'Consent') %></th>
38
+ <th><%= t('testimonials.dashboard.received', default: 'Received') %></th>
39
+ <th></th>
40
+ </tr>
41
+ </thead>
42
+ <tbody>
43
+ <% @testimonials.each do |testimonial| %>
44
+ <tr>
45
+ <td>
46
+ <% if testimonial.rating %>
47
+ <span class="stars"><%= '★' * testimonial.rating %><span class="off"><%= '★' * (5 - testimonial.rating) %></span></span>
48
+ <% end %>
49
+ </td>
50
+ <td>
51
+ <%= link_to testimonial_path(testimonial) do %>
52
+ <% if testimonial.body.present? %>
53
+ <%= truncate(testimonial.body, length: 110) %>
54
+ <% else %>
55
+ <em><%= t('testimonials.kinds.video', default: 'Video') %></em>
56
+ <% end %>
57
+ <% end %>
58
+ <% if testimonial.video_attached? %>
59
+ <div class="muted">🎥 <%= t('testimonials.kinds.video', default: 'Video') %></div>
60
+ <% end %>
61
+ <% if testimonial.featured? %>
62
+ <div class="muted">⭐ <%= t('testimonials.dashboard.featured', default: 'Featured') %></div>
63
+ <% end %>
64
+ </td>
65
+ <td>
66
+ <%= testimonial.display_name %>
67
+ <% if testimonial.title_company.present? %>
68
+ <div class="muted"><%= testimonial.title_company %></div>
69
+ <% end %>
70
+ </td>
71
+ <td><%= testimonial.consent_given? ? '✓' : '—' %></td>
72
+ <td class="muted" title="<%= testimonial.created_at %>">
73
+ <%= time_ago_in_words(testimonial.created_at) %>
74
+ </td>
75
+ <td class="row-actions">
76
+ <%# Inline status triage; feature / best line / delete live on the show page. %>
77
+ <% unless testimonial.approved? %>
78
+ <%= button_to t('testimonials.dashboard.move_to_approved', default: 'Approve'),
79
+ testimonial_path(testimonial),
80
+ method: :patch, params: { testimonial: { status: 'approved' } },
81
+ class: 'small primary' %>
82
+ <% end %>
83
+ <% unless testimonial.archived? %>
84
+ <%= button_to t('testimonials.dashboard.move_to_archived', default: 'Archive'),
85
+ testimonial_path(testimonial),
86
+ method: :patch, params: { testimonial: { status: 'archived' } },
87
+ class: 'small' %>
88
+ <% end %>
89
+ </td>
90
+ </tr>
91
+ <% end %>
92
+ </tbody>
93
+ </table>
94
+ <% else %>
95
+ <div class="empty"><%= t('testimonials.dashboard.empty', default: 'Nothing here yet.') %></div>
96
+ <% end %>
97
+ </div>
98
+
99
+ <div class="pager">
100
+ <% if @page > 1 %>
101
+ <%= link_to t('testimonials.dashboard.newer', default: '← Newer'),
102
+ testimonials_path(status: @status, kind: @kind, q: @query, page: @page - 1) %>
103
+ <% end %>
104
+ <% if @more %>
105
+ <%= link_to t('testimonials.dashboard.older', default: 'Older →'),
106
+ testimonials_path(status: @status, kind: @kind, q: @query, page: @page + 1) %>
107
+ <% end %>
108
+ </div>
@@ -0,0 +1,105 @@
1
+ <div class="breadcrumb">
2
+ <%= link_to t('testimonials.dashboard.title', default: 'Testimonials'), root_path %>
3
+ / #<%= @testimonial.id %>
4
+ </div>
5
+
6
+ <h1 class="title-row">
7
+ <span class="badge status-<%= @testimonial.status %>">
8
+ <%= t("testimonials.statuses.#{@testimonial.status}", default: @testimonial.status.humanize) %>
9
+ </span>
10
+ <% if @testimonial.featured? %>
11
+ <span class="badge status-approved">⭐ <%= t('testimonials.dashboard.featured', default: 'Featured') %></span>
12
+ <% end %>
13
+ <% if @testimonial.rating %>
14
+ <span class="stars"><%= '★' * @testimonial.rating %><span class="off"><%= '★' * (5 - @testimonial.rating) %></span></span>
15
+ <% end %>
16
+ </h1>
17
+
18
+ <div class="card pad" style="margin-bottom: 16px;">
19
+ <% if @testimonial.video_attached? %>
20
+ <%# #t=0.1 makes the browser paint that frame as the thumbnail. %>
21
+ <video class="playback" controls preload="metadata"
22
+ src="<%= testimonial_video_path(@testimonial) %>#t=0.1"></video>
23
+ <p class="muted">
24
+ <%= link_to "⬇ #{t('testimonials.dashboard.download_video', default: 'Download video')}",
25
+ testimonial_video_path(@testimonial, download: 1) %>
26
+ </p>
27
+ <% end %>
28
+ <% if @testimonial.body.present? %>
29
+ <p class="message"><%= @testimonial.body %></p>
30
+ <% end %>
31
+
32
+ <%# The customer's words are never edited — but the admin picks the line
33
+ worth featuring. %>
34
+ <%= form_with model: @testimonial, url: testimonial_path(@testimonial), method: :patch,
35
+ class: 'best-line-form', local: true do |form| %>
36
+ <label for="testimonial_best_line">
37
+ <%= t('testimonials.dashboard.best_line', default: 'Best line') %>
38
+ </label>
39
+ <p class="muted" style="margin: 2px 0 6px;">
40
+ <%= t('testimonials.dashboard.best_line_hint',
41
+ default: 'The quote your site will show. Leave blank to use the full text. For videos, type the best thing they said.') %>
42
+ </p>
43
+ <%= form.text_area :best_line, rows: 2, id: 'testimonial_best_line' %>
44
+ <button class="small" style="margin-top: 8px;">
45
+ <%= t('testimonials.dashboard.save_best_line', default: 'Save') %>
46
+ </button>
47
+ <% end %>
48
+ </div>
49
+
50
+ <div class="card pad" style="margin-bottom: 16px;">
51
+ <dl>
52
+ <dt><%= t('testimonials.dashboard.from', default: 'From') %></dt>
53
+ <dd>
54
+ <% if @testimonial.avatar_attached? %>
55
+ <img class="avatar" src="<%= testimonial_avatar_path(@testimonial) %>" alt="">
56
+ <% end %>
57
+ <%= @testimonial.display_name %>
58
+ <% if @testimonial.title_company.present? %> — <%= @testimonial.title_company %><% end %>
59
+ </dd>
60
+ <% if @testimonial.email.present? %>
61
+ <dt><%= t('testimonials.dashboard.email', default: 'Email') %></dt>
62
+ <dd><%= @testimonial.email %></dd>
63
+ <% end %>
64
+ <dt><%= t('testimonials.dashboard.consent', default: 'Consent') %></dt>
65
+ <dd>
66
+ <% if @testimonial.consent_given? %>
67
+ ✓ <span class="muted"><%= @testimonial.consent_text %></span>
68
+ <% else %>
69
+ — <span class="muted"><%= t('testimonials.dashboard.no_consent', default: 'No publication consent. Not served by the API.') %></span>
70
+ <% end %>
71
+ </dd>
72
+ <dt><%= t('testimonials.dashboard.source', default: 'Source') %></dt>
73
+ <dd><%= t("testimonials.sources.#{@testimonial.source}", default: @testimonial.source.humanize) %></dd>
74
+ <% if @testimonial.page_url.present? %>
75
+ <dt><%= t('testimonials.dashboard.page', default: 'Page') %></dt>
76
+ <dd><%= link_to @testimonial.page_url, @testimonial.page_url, target: '_blank', rel: 'noopener' %></dd>
77
+ <% end %>
78
+ <% if @testimonial.locale.present? %>
79
+ <dt><%= t('testimonials.dashboard.locale', default: 'Locale') %></dt>
80
+ <dd><%= @testimonial.locale %></dd>
81
+ <% end %>
82
+ <% if @testimonial.user_agent.present? %>
83
+ <dt><%= t('testimonials.dashboard.browser', default: 'Browser') %></dt>
84
+ <dd class="muted"><%= @testimonial.user_agent %></dd>
85
+ <% end %>
86
+ <dt><%= t('testimonials.dashboard.received', default: 'Received') %></dt>
87
+ <dd><%= @testimonial.created_at %></dd>
88
+ </dl>
89
+ </div>
90
+
91
+ <div class="actions">
92
+ <% (Testimonials::Testimonial::STATUSES - [@testimonial.status]).each do |status| %>
93
+ <%= button_to t("testimonials.dashboard.move_to_#{status}", default: "Mark #{status.humanize.downcase}"),
94
+ testimonial_path(@testimonial),
95
+ method: :patch, params: { testimonial: { status: status } },
96
+ class: ('primary' if status == 'approved') %>
97
+ <% end %>
98
+ <%= button_to (@testimonial.featured? ? t('testimonials.dashboard.unfeature', default: 'Unfeature') : t('testimonials.dashboard.feature', default: 'Feature')),
99
+ testimonial_path(@testimonial),
100
+ method: :patch, params: { testimonial: { featured: !@testimonial.featured? } } %>
101
+ <%= button_to t('testimonials.dashboard.delete', default: 'Delete'),
102
+ testimonial_path(@testimonial),
103
+ method: :delete, class: 'danger',
104
+ form: { data: { confirm: t('testimonials.dashboard.delete_confirm', default: 'Delete this testimonial?') } } %>
105
+ </div>
@@ -0,0 +1,101 @@
1
+ ar:
2
+ testimonials:
3
+ questions:
4
+ - "من أنت وكيف تستخدم %{app}؟"
5
+ - "كيف ساعدك %{app}؟"
6
+ - "ما أفضل ما في %{app}؟"
7
+ consent: "أسمح باستخدام هذه الشهادة عبر وسائل التواصل الاجتماعي وجهود تسويقية أخرى."
8
+ cta: "اترك تقييمًا"
9
+ update_title: "حدِّث تقييمك"
10
+ enjoying: "هل يعجبك %{app}؟"
11
+ not_now: "ليس الآن"
12
+ rate_aria: "قيّم %{count} من 5"
13
+ share_title: "شارك تجربتك"
14
+ promoter_title: "يسعدنا سماع ذلك! هل تمانع قوله علنًا؟"
15
+ questions_title: "أسئلة"
16
+ message: "شهادتك"
17
+ message_placeholder: "ماذا ستقول لصديق عن %{app}؟"
18
+ record_video: "تسجيل فيديو"
19
+ record_video_hint: "فيديو قصير يقول أكثر من صفحة نص."
20
+ name: "اسمك"
21
+ email: "بريدك الإلكتروني"
22
+ title_company: "المنصب، الشركة"
23
+ photo: "صورتك"
24
+ optional: "اختياري"
25
+ submit: "إرسال"
26
+ cancel: "إلغاء"
27
+ close: "إغلاق"
28
+ thanks: "شكرًا جزيلًا!"
29
+ video_check_title: "فحص الكاميرا"
30
+ video_hint: "حتى %{seconds} ثانية. يمكنك مراجعته قبل الإرسال."
31
+ start_recording: "بدء التسجيل"
32
+ stop_recording: "إنهاء"
33
+ record_again: "إعادة التسجيل"
34
+ use_video: "استخدام هذا الفيديو"
35
+ upload_instead: "رفع ملف فيديو بدلًا من ذلك"
36
+ video_attached: "تم إرفاق الفيديو"
37
+ remove: "إزالة"
38
+ nps_question: "ما مدى احتمال أن توصي بـ %{app} لصديق أو زميل؟"
39
+ nps_low: "غير محتمل إطلاقًا"
40
+ nps_high: "محتمل جدًا"
41
+ nps_comment_label: "ما السبب الرئيسي لتقييمك؟"
42
+ error_blank: "يرجى كتابة شيء أو تسجيل فيديو."
43
+ error_contact: "يرجى إدخال اسمك وبريدك الإلكتروني."
44
+ error_save: "تعذّر الإرسال. حاول مرة أخرى."
45
+ error_video_too_large: "الفيديو كبير جدًا (بحد أقصى %{size} ميغابايت)."
46
+ error_camera: "تعذّر الوصول إلى الكاميرا. يمكنك رفع ملف فيديو بدلًا من ذلك."
47
+ error_rate_limited: "إرسالات كثيرة جدًا. يرجى الانتظار قليلًا والمحاولة مجددًا."
48
+ page:
49
+ title: "شارك تجربتك مع %{app}"
50
+ subtitle: "كلماتك تساعد الآخرين على اتخاذ القرار — شكرًا لك!"
51
+ kinds:
52
+ text: "نص"
53
+ video: "فيديو"
54
+ sources:
55
+ widget: "أداة داخل التطبيق"
56
+ page: "صفحة الجمع"
57
+ nps: "متابعة NPS"
58
+ collection_page: "اطلب شهادات"
59
+ download_video: "تنزيل الفيديو"
60
+ statuses:
61
+ pending: "قيد الانتظار"
62
+ approved: "معتمد"
63
+ archived: "مؤرشف"
64
+ dashboard:
65
+ title: "الشهادات"
66
+ nps: "NPS"
67
+ all_kinds: "كل الأنواع"
68
+ search: "بحث"
69
+ search_placeholder: "ابحث في النص والاسم والبريد…"
70
+ rating: "التقييم"
71
+ testimonial: "الشهادة"
72
+ from: "من"
73
+ consent: "الموافقة"
74
+ no_consent: "لا موافقة على النشر. لا تُقدَّم عبر واجهة البرمجة."
75
+ received: "تاريخ الاستلام"
76
+ featured: "مميّز"
77
+ approve: "اعتماد"
78
+ feature: "تمييز"
79
+ unfeature: "إلغاء التمييز"
80
+ best_line: "أفضل جملة"
81
+ best_line_hint: "الاقتباس الذي سيعرضه موقعك. اتركه فارغًا لاستخدام النص الكامل. للفيديو، اكتب أفضل جملة قالوها."
82
+ save_best_line: "حفظ"
83
+ email: "البريد الإلكتروني"
84
+ source: "المصدر"
85
+ page: "الصفحة"
86
+ locale: "اللغة"
87
+ browser: "المتصفح"
88
+ empty: "لا شيء هنا بعد."
89
+ newer: "→ الأحدث"
90
+ older: "الأقدم ←"
91
+ move_to_pending: "وضع قيد الانتظار"
92
+ move_to_approved: "اعتماد"
93
+ move_to_archived: "أرشفة"
94
+ delete: "حذف"
95
+ delete_confirm: "حذف هذه الشهادة؟"
96
+ nps_score: "درجة NPS"
97
+ promoters: "المروّجون (9–10)"
98
+ passives: "المحايدون (7–8)"
99
+ detractors: "المنتقدون (0–6)"
100
+ score: "الدرجة"
101
+ comment: "التعليق"
@@ -0,0 +1,101 @@
1
+ bg:
2
+ testimonials:
3
+ questions:
4
+ - "Кой сте вие и как използвате %{app}?"
5
+ - "Как %{app} ви помогна?"
6
+ - "Кое е най-хубавото на %{app}?"
7
+ consent: "Разрешавам този отзив да се използва в социалните мрежи и други маркетингови дейности."
8
+ cta: "Оставете отзив"
9
+ update_title: "Обновете отзива си"
10
+ enjoying: "Харесва ли ви %{app}?"
11
+ not_now: "Не сега"
12
+ rate_aria: "Оценете с %{count} от 5"
13
+ share_title: "Споделете опита си"
14
+ promoter_title: "Радваме се да го чуем! Бихте ли го казали публично?"
15
+ questions_title: "Въпроси"
16
+ message: "Вашият отзив"
17
+ message_placeholder: "Какво бихте казали на приятел за %{app}?"
18
+ record_video: "Запишете видео"
19
+ record_video_hint: "Кратко видео казва повече от страница текст."
20
+ name: "Вашето име"
21
+ email: "Вашият имейл"
22
+ title_company: "Длъжност, фирма"
23
+ photo: "Вашата снимка"
24
+ optional: "по избор"
25
+ submit: "Изпрати"
26
+ cancel: "Отказ"
27
+ close: "Затвори"
28
+ thanks: "Много благодарим!"
29
+ video_check_title: "Проверка на камерата"
30
+ video_hint: "До %{seconds} секунди. Можете да го прегледате преди изпращане."
31
+ start_recording: "Започни запис"
32
+ stop_recording: "Готово"
33
+ record_again: "Запиши отново"
34
+ use_video: "Използвай това видео"
35
+ upload_instead: "Качете видеофайл вместо това"
36
+ video_attached: "Видеото е прикачено"
37
+ remove: "Премахни"
38
+ nps_question: "Колко вероятно е да препоръчате %{app} на приятел или колега?"
39
+ nps_low: "Никак не е вероятно"
40
+ nps_high: "Изключително вероятно"
41
+ nps_comment_label: "Каква е основната причина за вашата оценка?"
42
+ error_blank: "Моля, напишете нещо или запишете видео."
43
+ error_contact: "Моля, въведете вашето име и имейл."
44
+ error_save: "Изпращането не успя. Опитайте отново."
45
+ error_video_too_large: "Видеото е твърде голямо (макс. %{size} MB)."
46
+ error_camera: "Няма достъп до камерата. Можете да качите видеофайл вместо това."
47
+ error_rate_limited: "Твърде много изпращания. Изчакайте малко и опитайте отново."
48
+ page:
49
+ title: "Споделете опита си с %{app}"
50
+ subtitle: "Вашите думи помагат на другите да решат — благодарим!"
51
+ kinds:
52
+ text: "Текст"
53
+ video: "Видео"
54
+ sources:
55
+ widget: "Уиджет в приложението"
56
+ page: "Страница за събиране"
57
+ nps: "Продължение след NPS"
58
+ collection_page: "Поискайте отзиви"
59
+ download_video: "Изтегляне на видеото"
60
+ statuses:
61
+ pending: "Чакащи"
62
+ approved: "Одобрени"
63
+ archived: "Архивирани"
64
+ dashboard:
65
+ title: "Отзиви"
66
+ nps: "NPS"
67
+ all_kinds: "Всички видове"
68
+ search: "Търсене"
69
+ search_placeholder: "Търсете текст, име, имейл…"
70
+ rating: "Оценка"
71
+ testimonial: "Отзив"
72
+ from: "От"
73
+ consent: "Съгласие"
74
+ no_consent: "Няма съгласие за публикуване. Не се предоставя през API."
75
+ received: "Получено"
76
+ featured: "Избрано"
77
+ approve: "Одобри"
78
+ feature: "Направи избрано"
79
+ unfeature: "Премахни от избрани"
80
+ best_line: "Най-добрата фраза"
81
+ best_line_hint: "Цитатът, който сайтът ви ще показва. Оставете празно за целия текст. При видео впишете най-добрата казана фраза."
82
+ save_best_line: "Запази"
83
+ email: "Имейл"
84
+ source: "Източник"
85
+ page: "Страница"
86
+ locale: "Език"
87
+ browser: "Браузър"
88
+ empty: "Тук още няма нищо."
89
+ newer: "← По-нови"
90
+ older: "По-стари →"
91
+ move_to_pending: "Маркирай като чакащо"
92
+ move_to_approved: "Одобри"
93
+ move_to_archived: "Архивирай"
94
+ delete: "Изтрий"
95
+ delete_confirm: "Да се изтрие ли този отзив?"
96
+ nps_score: "NPS резултат"
97
+ promoters: "Промоутъри (9–10)"
98
+ passives: "Неутрални (7–8)"
99
+ detractors: "Критици (0–6)"
100
+ score: "Резултат"
101
+ comment: "Коментар"
@@ -0,0 +1,101 @@
1
+ bn:
2
+ testimonials:
3
+ questions:
4
+ - "আপনি কে এবং কীভাবে %{app} ব্যবহার করেন?"
5
+ - "%{app} আপনাকে কীভাবে সাহায্য করেছে?"
6
+ - "%{app}-এর সবচেয়ে ভালো দিক কী?"
7
+ consent: "আমি এই প্রশংসাপত্রটি সোশ্যাল মিডিয়া ও অন্যান্য মার্কেটিং কাজে ব্যবহারের অনুমতি দিচ্ছি।"
8
+ cta: "রিভিউ লিখুন"
9
+ update_title: "আপনার রিভিউ আপডেট করুন"
10
+ enjoying: "%{app} ভালো লাগছে?"
11
+ not_now: "এখন নয়"
12
+ rate_aria: "৫-এর মধ্যে %{count} দিন"
13
+ share_title: "আপনার অভিজ্ঞতা শেয়ার করুন"
14
+ promoter_title: "শুনে ভালো লাগল! এটা কি প্রকাশ্যে বলবেন?"
15
+ questions_title: "প্রশ্ন"
16
+ message: "আপনার মতামত"
17
+ message_placeholder: "%{app} সম্পর্কে বন্ধুকে কী বলবেন?"
18
+ record_video: "ভিডিও রেকর্ড করুন"
19
+ record_video_hint: "একটি ছোট ভিডিও এক পাতা লেখার চেয়ে বেশি কিছু বলে।"
20
+ name: "আপনার নাম"
21
+ email: "আপনার ইমেইল"
22
+ title_company: "পদবি, কোম্পানি"
23
+ photo: "আপনার ছবি"
24
+ optional: "ঐচ্ছিক"
25
+ submit: "পাঠান"
26
+ cancel: "বাতিল"
27
+ close: "বন্ধ করুন"
28
+ thanks: "অসংখ্য ধন্যবাদ!"
29
+ video_check_title: "ক্যামেরা পরীক্ষা"
30
+ video_hint: "সর্বোচ্চ %{seconds} সেকেন্ড। পাঠানোর আগে দেখে নিতে পারবেন।"
31
+ start_recording: "রেকর্ডিং শুরু করুন"
32
+ stop_recording: "শেষ করুন"
33
+ record_again: "আবার রেকর্ড করুন"
34
+ use_video: "এই ভিডিওটি ব্যবহার করুন"
35
+ upload_instead: "এর বদলে ভিডিও ফাইল আপলোড করুন"
36
+ video_attached: "ভিডিও সংযুক্ত"
37
+ remove: "সরান"
38
+ nps_question: "বন্ধু বা সহকর্মীকে %{app} সুপারিশ করার সম্ভাবনা কতটা?"
39
+ nps_low: "একেবারেই সম্ভাবনা নেই"
40
+ nps_high: "অত্যন্ত সম্ভাবনা আছে"
41
+ nps_comment_label: "আপনার স্কোরের মূল কারণ কী?"
42
+ error_blank: "কিছু লিখুন বা একটি ভিডিও রেকর্ড করুন।"
43
+ error_contact: "আপনার নাম ও ইমেইল লিখুন।"
44
+ error_save: "পাঠানো যায়নি। আবার চেষ্টা করুন।"
45
+ error_video_too_large: "ভিডিওটি খুব বড় (সর্বোচ্চ %{size} MB)।"
46
+ error_camera: "ক্যামেরায় প্রবেশ করা যায়নি। এর বদলে ভিডিও ফাইল আপলোড করতে পারেন।"
47
+ error_rate_limited: "অনেক বেশি জমা পড়েছে। একটু অপেক্ষা করে আবার চেষ্টা করুন।"
48
+ page:
49
+ title: "%{app} নিয়ে আপনার অভিজ্ঞতা শেয়ার করুন"
50
+ subtitle: "আপনার কথা অন্যদের সিদ্ধান্ত নিতে সাহায্য করে — ধন্যবাদ!"
51
+ kinds:
52
+ text: "লেখা"
53
+ video: "ভিডিও"
54
+ sources:
55
+ widget: "অ্যাপের ভেতরের উইজেট"
56
+ page: "সংগ্রহ পাতা"
57
+ nps: "NPS ফলো-আপ"
58
+ collection_page: "প্রশংসাপত্র চান"
59
+ download_video: "ভিডিও ডাউনলোড করুন"
60
+ statuses:
61
+ pending: "অপেক্ষমাণ"
62
+ approved: "অনুমোদিত"
63
+ archived: "আর্কাইভ করা"
64
+ dashboard:
65
+ title: "প্রশংসাপত্র"
66
+ nps: "NPS"
67
+ all_kinds: "সব ধরন"
68
+ search: "খুঁজুন"
69
+ search_placeholder: "লেখা, নাম, ইমেইল খুঁজুন…"
70
+ rating: "রেটিং"
71
+ testimonial: "প্রশংসাপত্র"
72
+ from: "প্রেরক"
73
+ consent: "সম্মতি"
74
+ no_consent: "প্রকাশের সম্মতি নেই। API দিয়ে দেওয়া হয় না।"
75
+ received: "গৃহীত"
76
+ featured: "বিশেষ"
77
+ approve: "অনুমোদন"
78
+ feature: "বিশেষ করুন"
79
+ unfeature: "বিশেষ থেকে সরান"
80
+ best_line: "সেরা লাইন"
81
+ best_line_hint: "আপনার সাইটে যে উক্তিটি দেখানো হবে। পুরো লেখা ব্যবহার করতে খালি রাখুন। ভিডিওর ক্ষেত্রে তাদের বলা সেরা কথাটি লিখুন।"
82
+ save_best_line: "সংরক্ষণ"
83
+ email: "ইমেইল"
84
+ source: "উৎস"
85
+ page: "পাতা"
86
+ locale: "ভাষা"
87
+ browser: "ব্রাউজার"
88
+ empty: "এখনও এখানে কিছু নেই।"
89
+ newer: "← নতুন"
90
+ older: "পুরনো →"
91
+ move_to_pending: "অপেক্ষমাণ চিহ্নিত করুন"
92
+ move_to_approved: "অনুমোদন"
93
+ move_to_archived: "আর্কাইভ করুন"
94
+ delete: "মুছুন"
95
+ delete_confirm: "এই প্রশংসাপত্রটি মুছবেন?"
96
+ nps_score: "NPS স্কোর"
97
+ promoters: "প্রোমোটার (৯–১০)"
98
+ passives: "নিরপেক্ষ (৭–৮)"
99
+ detractors: "সমালোচক (০–৬)"
100
+ score: "স্কোর"
101
+ comment: "মন্তব্য"