testimonials 0.7.4 → 0.7.6
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/README.md +26 -6
- data/app/controllers/testimonials/collection_controller.rb +20 -6
- data/app/views/layouts/testimonials/application.html.erb +2 -7
- data/app/views/layouts/testimonials/collection.html.erb +2 -1
- data/app/views/testimonials/collection/nps.html.erb +14 -0
- data/app/views/testimonials/nps_responses/index.html.erb +12 -1
- data/app/views/testimonials/testimonials/_testimonial_panel.html.erb +15 -15
- data/app/views/testimonials/testimonials/index.html.erb +11 -1
- data/config/locales/testimonials.ar.yml +5 -2
- data/config/locales/testimonials.bg.yml +5 -2
- data/config/locales/testimonials.bn.yml +5 -2
- data/config/locales/testimonials.de.yml +5 -2
- data/config/locales/testimonials.el.yml +5 -2
- data/config/locales/testimonials.en.yml +5 -2
- data/config/locales/testimonials.es.yml +5 -2
- data/config/locales/testimonials.fr.yml +5 -2
- data/config/locales/testimonials.hi.yml +5 -2
- data/config/locales/testimonials.hr.yml +5 -2
- data/config/locales/testimonials.id.yml +5 -2
- data/config/locales/testimonials.it.yml +5 -2
- data/config/locales/testimonials.ja.yml +5 -2
- data/config/locales/testimonials.ko.yml +5 -2
- data/config/locales/testimonials.lb.yml +5 -2
- data/config/locales/testimonials.nl.yml +5 -2
- data/config/locales/testimonials.pl.yml +5 -2
- data/config/locales/testimonials.pt.yml +5 -2
- data/config/locales/testimonials.ro.yml +5 -2
- data/config/locales/testimonials.ru.yml +5 -2
- data/config/locales/testimonials.th.yml +5 -2
- data/config/locales/testimonials.tr.yml +5 -2
- data/config/locales/testimonials.uk.yml +5 -2
- data/config/locales/testimonials.ur.yml +5 -2
- data/config/locales/testimonials.vi.yml +5 -2
- data/config/locales/testimonials.zh-CN.yml +5 -2
- data/config/routes.rb +1 -0
- data/lib/generators/testimonials/install/install_generator.rb +1 -0
- data/lib/tasks/testimonials_tasks.rake +11 -0
- data/lib/testimonials/dashboard.css +6 -2
- data/lib/testimonials/demo/README.md +7 -0
- data/lib/testimonials/demo/flower.mp4 +0 -0
- data/lib/testimonials/engine.rb +4 -0
- data/lib/testimonials/seeds.rb +164 -0
- data/lib/testimonials/version.rb +1 -1
- data/lib/testimonials/widget.js +28 -9
- data/lib/testimonials.rb +1 -0
- metadata +6 -1
|
@@ -50,6 +50,8 @@ ko:
|
|
|
50
50
|
page:
|
|
51
51
|
title: "%{app} 사용 경험을 공유해 주세요"
|
|
52
52
|
subtitle: "당신의 이야기가 다른 사람의 결정을 돕습니다 — 감사합니다!"
|
|
53
|
+
nps_title: "%{app} 개선에 도움을 주세요"
|
|
54
|
+
nps_subtitle: "질문 하나 — 10초면 끝납니다."
|
|
53
55
|
kinds:
|
|
54
56
|
text: "텍스트"
|
|
55
57
|
video: "동영상"
|
|
@@ -57,8 +59,6 @@ ko:
|
|
|
57
59
|
widget: "앱 내 위젯"
|
|
58
60
|
page: "수집 페이지"
|
|
59
61
|
nps: "NPS 후속"
|
|
60
|
-
collection_page: "후기 요청하기"
|
|
61
|
-
download_video: "동영상 다운로드"
|
|
62
62
|
statuses:
|
|
63
63
|
pending: "대기 중"
|
|
64
64
|
approved: "승인됨"
|
|
@@ -66,6 +66,9 @@ ko:
|
|
|
66
66
|
dashboard:
|
|
67
67
|
title: "Testimonials"
|
|
68
68
|
nps: "NPS"
|
|
69
|
+
nps_page: "NPS 점수 요청하기"
|
|
70
|
+
collection_page: "후기 요청하기"
|
|
71
|
+
download_video: "동영상 다운로드"
|
|
69
72
|
all_kinds: "모든 유형"
|
|
70
73
|
search: "검색"
|
|
71
74
|
search_placeholder: "텍스트, 이름, 이메일 검색…"
|
|
@@ -50,6 +50,8 @@ lb:
|
|
|
50
50
|
page:
|
|
51
51
|
title: "Deelt Är Erfarung mat %{app}"
|
|
52
52
|
subtitle: "Är Wierder hëllefen aneren ze entscheeden — merci!"
|
|
53
|
+
nps_title: "Hëlleft ons %{app} ze verbesseren"
|
|
54
|
+
nps_subtitle: "Eng kuerz Fro — dauert zéng Sekonnen."
|
|
53
55
|
kinds:
|
|
54
56
|
text: "Text"
|
|
55
57
|
video: "Video"
|
|
@@ -57,8 +59,6 @@ lb:
|
|
|
57
59
|
widget: "In-App-Widget"
|
|
58
60
|
page: "Sammelsäit"
|
|
59
61
|
nps: "NPS-Suivi"
|
|
60
|
-
collection_page: "Frot no Temoignagen"
|
|
61
|
-
download_video: "Video eroflueden"
|
|
62
62
|
statuses:
|
|
63
63
|
pending: "Am Waardestand"
|
|
64
64
|
approved: "Guttgeheescht"
|
|
@@ -66,6 +66,9 @@ lb:
|
|
|
66
66
|
dashboard:
|
|
67
67
|
title: "Testimonials"
|
|
68
68
|
nps: "NPS"
|
|
69
|
+
nps_page: "No NPS-Bewäertunge froen"
|
|
70
|
+
collection_page: "Frot no Temoignagen"
|
|
71
|
+
download_video: "Video eroflueden"
|
|
69
72
|
all_kinds: "All Zorten"
|
|
70
73
|
search: "Sichen"
|
|
71
74
|
search_placeholder: "Text, Numm, E-Mail sichen…"
|
|
@@ -50,6 +50,8 @@ nl:
|
|
|
50
50
|
page:
|
|
51
51
|
title: "Deel je ervaring met %{app}"
|
|
52
52
|
subtitle: "Jouw woorden helpen anderen beslissen — bedankt!"
|
|
53
|
+
nps_title: "Help ons %{app} te verbeteren"
|
|
54
|
+
nps_subtitle: "Eén korte vraag — het kost tien seconden."
|
|
53
55
|
kinds:
|
|
54
56
|
text: "Tekst"
|
|
55
57
|
video: "Video"
|
|
@@ -57,8 +59,6 @@ nl:
|
|
|
57
59
|
widget: "In-app widget"
|
|
58
60
|
page: "Verzamelpagina"
|
|
59
61
|
nps: "NPS-opvolging"
|
|
60
|
-
collection_page: "Vraag om testimonials"
|
|
61
|
-
download_video: "Video downloaden"
|
|
62
62
|
statuses:
|
|
63
63
|
pending: "In afwachting"
|
|
64
64
|
approved: "Goedgekeurd"
|
|
@@ -66,6 +66,9 @@ nl:
|
|
|
66
66
|
dashboard:
|
|
67
67
|
title: "Testimonials"
|
|
68
68
|
nps: "NPS"
|
|
69
|
+
nps_page: "Om NPS-scores vragen"
|
|
70
|
+
collection_page: "Vraag om testimonials"
|
|
71
|
+
download_video: "Video downloaden"
|
|
69
72
|
all_kinds: "Alle soorten"
|
|
70
73
|
search: "Zoeken"
|
|
71
74
|
search_placeholder: "Zoek tekst, naam, e-mail…"
|
|
@@ -50,6 +50,8 @@ pl:
|
|
|
50
50
|
page:
|
|
51
51
|
title: "Podziel się swoim doświadczeniem z %{app}"
|
|
52
52
|
subtitle: "Twoje słowa pomagają innym podjąć decyzję — dziękujemy!"
|
|
53
|
+
nps_title: "Pomóż nam ulepszyć %{app}"
|
|
54
|
+
nps_subtitle: "Jedno krótkie pytanie — zajmie dziesięć sekund."
|
|
53
55
|
kinds:
|
|
54
56
|
text: "Tekst"
|
|
55
57
|
video: "Wideo"
|
|
@@ -57,8 +59,6 @@ pl:
|
|
|
57
59
|
widget: "Widżet w aplikacji"
|
|
58
60
|
page: "Strona zbierania"
|
|
59
61
|
nps: "Kontynuacja NPS"
|
|
60
|
-
collection_page: "Poproś o opinie"
|
|
61
|
-
download_video: "Pobierz wideo"
|
|
62
62
|
statuses:
|
|
63
63
|
pending: "Oczekujące"
|
|
64
64
|
approved: "Zatwierdzone"
|
|
@@ -66,6 +66,9 @@ pl:
|
|
|
66
66
|
dashboard:
|
|
67
67
|
title: "Testimonials"
|
|
68
68
|
nps: "NPS"
|
|
69
|
+
nps_page: "Poproś o oceny NPS"
|
|
70
|
+
collection_page: "Poproś o opinie"
|
|
71
|
+
download_video: "Pobierz wideo"
|
|
69
72
|
all_kinds: "Wszystkie rodzaje"
|
|
70
73
|
search: "Szukaj"
|
|
71
74
|
search_placeholder: "Szukaj tekstu, imienia, e-maila…"
|
|
@@ -50,6 +50,8 @@ pt:
|
|
|
50
50
|
page:
|
|
51
51
|
title: "Compartilhe sua experiência com %{app}"
|
|
52
52
|
subtitle: "Suas palavras ajudam outras pessoas a decidir — obrigado!"
|
|
53
|
+
nps_title: "Ajude-nos a melhorar o %{app}"
|
|
54
|
+
nps_subtitle: "Uma pergunta rápida — leva dez segundos."
|
|
53
55
|
kinds:
|
|
54
56
|
text: "Texto"
|
|
55
57
|
video: "Vídeo"
|
|
@@ -57,8 +59,6 @@ pt:
|
|
|
57
59
|
widget: "Widget no app"
|
|
58
60
|
page: "Página de coleta"
|
|
59
61
|
nps: "Acompanhamento NPS"
|
|
60
|
-
collection_page: "Pedir depoimentos"
|
|
61
|
-
download_video: "Baixar o vídeo"
|
|
62
62
|
statuses:
|
|
63
63
|
pending: "Pendente"
|
|
64
64
|
approved: "Aprovado"
|
|
@@ -66,6 +66,9 @@ pt:
|
|
|
66
66
|
dashboard:
|
|
67
67
|
title: "Testimonials"
|
|
68
68
|
nps: "NPS"
|
|
69
|
+
nps_page: "Pedir pontuações NPS"
|
|
70
|
+
collection_page: "Pedir depoimentos"
|
|
71
|
+
download_video: "Baixar o vídeo"
|
|
69
72
|
all_kinds: "Todos os tipos"
|
|
70
73
|
search: "Buscar"
|
|
71
74
|
search_placeholder: "Buscar texto, nome, e-mail…"
|
|
@@ -50,6 +50,8 @@ ro:
|
|
|
50
50
|
page:
|
|
51
51
|
title: "Împărtășiți-vă experiența cu %{app}"
|
|
52
52
|
subtitle: "Cuvintele dvs. îi ajută pe alții să decidă — mulțumim!"
|
|
53
|
+
nps_title: "Ajutați-ne să îmbunătățim %{app}"
|
|
54
|
+
nps_subtitle: "O întrebare rapidă — durează zece secunde."
|
|
53
55
|
kinds:
|
|
54
56
|
text: "Text"
|
|
55
57
|
video: "Video"
|
|
@@ -57,8 +59,6 @@ ro:
|
|
|
57
59
|
widget: "Widget în aplicație"
|
|
58
60
|
page: "Pagină de colectare"
|
|
59
61
|
nps: "Continuare NPS"
|
|
60
|
-
collection_page: "Cere testimoniale"
|
|
61
|
-
download_video: "Descarcă videoclipul"
|
|
62
62
|
statuses:
|
|
63
63
|
pending: "În așteptare"
|
|
64
64
|
approved: "Aprobat"
|
|
@@ -66,6 +66,9 @@ ro:
|
|
|
66
66
|
dashboard:
|
|
67
67
|
title: "Testimonials"
|
|
68
68
|
nps: "NPS"
|
|
69
|
+
nps_page: "Cere scoruri NPS"
|
|
70
|
+
collection_page: "Cere testimoniale"
|
|
71
|
+
download_video: "Descarcă videoclipul"
|
|
69
72
|
all_kinds: "Toate tipurile"
|
|
70
73
|
search: "Căutare"
|
|
71
74
|
search_placeholder: "Căutați text, nume, email…"
|
|
@@ -50,6 +50,8 @@ ru:
|
|
|
50
50
|
page:
|
|
51
51
|
title: "Поделитесь своим опытом с %{app}"
|
|
52
52
|
subtitle: "Ваши слова помогают другим решиться — спасибо!"
|
|
53
|
+
nps_title: "Помогите нам улучшить %{app}"
|
|
54
|
+
nps_subtitle: "Один короткий вопрос — займёт десять секунд."
|
|
53
55
|
kinds:
|
|
54
56
|
text: "Текст"
|
|
55
57
|
video: "Видео"
|
|
@@ -57,8 +59,6 @@ ru:
|
|
|
57
59
|
widget: "Виджет в приложении"
|
|
58
60
|
page: "Страница сбора"
|
|
59
61
|
nps: "После NPS"
|
|
60
|
-
collection_page: "Попросить отзывы"
|
|
61
|
-
download_video: "Скачать видео"
|
|
62
62
|
statuses:
|
|
63
63
|
pending: "Ожидает"
|
|
64
64
|
approved: "Одобрено"
|
|
@@ -66,6 +66,9 @@ ru:
|
|
|
66
66
|
dashboard:
|
|
67
67
|
title: "Testimonials"
|
|
68
68
|
nps: "NPS"
|
|
69
|
+
nps_page: "Запросить оценки NPS"
|
|
70
|
+
collection_page: "Попросить отзывы"
|
|
71
|
+
download_video: "Скачать видео"
|
|
69
72
|
all_kinds: "Все типы"
|
|
70
73
|
search: "Поиск"
|
|
71
74
|
search_placeholder: "Искать текст, имя, почту…"
|
|
@@ -50,6 +50,8 @@ th:
|
|
|
50
50
|
page:
|
|
51
51
|
title: "แบ่งปันประสบการณ์ของคุณกับ %{app}"
|
|
52
52
|
subtitle: "คำพูดของคุณช่วยให้คนอื่นตัดสินใจได้ — ขอบคุณ!"
|
|
53
|
+
nps_title: "ช่วยเราปรับปรุง %{app}"
|
|
54
|
+
nps_subtitle: "คำถามเดียวสั้น ๆ — ใช้เวลาสิบวินาที"
|
|
53
55
|
kinds:
|
|
54
56
|
text: "ข้อความ"
|
|
55
57
|
video: "วิดีโอ"
|
|
@@ -57,8 +59,6 @@ th:
|
|
|
57
59
|
widget: "วิดเจ็ตในแอป"
|
|
58
60
|
page: "หน้ารวบรวม"
|
|
59
61
|
nps: "ติดตามผล NPS"
|
|
60
|
-
collection_page: "ขอคำรับรอง"
|
|
61
|
-
download_video: "ดาวน์โหลดวิดีโอ"
|
|
62
62
|
statuses:
|
|
63
63
|
pending: "รอดำเนินการ"
|
|
64
64
|
approved: "อนุมัติแล้ว"
|
|
@@ -66,6 +66,9 @@ th:
|
|
|
66
66
|
dashboard:
|
|
67
67
|
title: "Testimonials"
|
|
68
68
|
nps: "NPS"
|
|
69
|
+
nps_page: "ขอคะแนน NPS"
|
|
70
|
+
collection_page: "ขอคำรับรอง"
|
|
71
|
+
download_video: "ดาวน์โหลดวิดีโอ"
|
|
69
72
|
all_kinds: "ทุกประเภท"
|
|
70
73
|
search: "ค้นหา"
|
|
71
74
|
search_placeholder: "ค้นหาข้อความ ชื่อ อีเมล…"
|
|
@@ -50,6 +50,8 @@ tr:
|
|
|
50
50
|
page:
|
|
51
51
|
title: "%{app} deneyiminizi paylaşın"
|
|
52
52
|
subtitle: "Sözleriniz başkalarının karar vermesine yardımcı olur — teşekkürler!"
|
|
53
|
+
nps_title: "%{app} deneyimini iyileştirmemize yardım edin"
|
|
54
|
+
nps_subtitle: "Tek bir kısa soru — on saniye sürer."
|
|
53
55
|
kinds:
|
|
54
56
|
text: "Metin"
|
|
55
57
|
video: "Video"
|
|
@@ -57,8 +59,6 @@ tr:
|
|
|
57
59
|
widget: "Uygulama içi bileşen"
|
|
58
60
|
page: "Toplama sayfası"
|
|
59
61
|
nps: "NPS takibi"
|
|
60
|
-
collection_page: "Görüş isteyin"
|
|
61
|
-
download_video: "Videoyu indir"
|
|
62
62
|
statuses:
|
|
63
63
|
pending: "Beklemede"
|
|
64
64
|
approved: "Onaylandı"
|
|
@@ -66,6 +66,9 @@ tr:
|
|
|
66
66
|
dashboard:
|
|
67
67
|
title: "Testimonials"
|
|
68
68
|
nps: "NPS"
|
|
69
|
+
nps_page: "NPS puanı isteyin"
|
|
70
|
+
collection_page: "Görüş isteyin"
|
|
71
|
+
download_video: "Videoyu indir"
|
|
69
72
|
all_kinds: "Tüm türler"
|
|
70
73
|
search: "Ara"
|
|
71
74
|
search_placeholder: "Metin, ad, e-posta ara…"
|
|
@@ -50,6 +50,8 @@ uk:
|
|
|
50
50
|
page:
|
|
51
51
|
title: "Поділіться своїм досвідом із %{app}"
|
|
52
52
|
subtitle: "Ваші слова допомагають іншим зважитися — дякуємо!"
|
|
53
|
+
nps_title: "Допоможіть нам покращити %{app}"
|
|
54
|
+
nps_subtitle: "Одне коротке питання — займе десять секунд."
|
|
53
55
|
kinds:
|
|
54
56
|
text: "Текст"
|
|
55
57
|
video: "Відео"
|
|
@@ -57,8 +59,6 @@ uk:
|
|
|
57
59
|
widget: "Віджет у застосунку"
|
|
58
60
|
page: "Сторінка збору"
|
|
59
61
|
nps: "Після NPS"
|
|
60
|
-
collection_page: "Попросити відгуки"
|
|
61
|
-
download_video: "Завантажити відео"
|
|
62
62
|
statuses:
|
|
63
63
|
pending: "Очікує"
|
|
64
64
|
approved: "Схвалено"
|
|
@@ -66,6 +66,9 @@ uk:
|
|
|
66
66
|
dashboard:
|
|
67
67
|
title: "Testimonials"
|
|
68
68
|
nps: "NPS"
|
|
69
|
+
nps_page: "Запитати оцінки NPS"
|
|
70
|
+
collection_page: "Попросити відгуки"
|
|
71
|
+
download_video: "Завантажити відео"
|
|
69
72
|
all_kinds: "Усі типи"
|
|
70
73
|
search: "Пошук"
|
|
71
74
|
search_placeholder: "Шукати текст, ім'я, пошту…"
|
|
@@ -50,6 +50,8 @@ ur:
|
|
|
50
50
|
page:
|
|
51
51
|
title: "%{app} کے ساتھ اپنا تجربہ شیئر کریں"
|
|
52
52
|
subtitle: "آپ کے الفاظ دوسروں کو فیصلہ کرنے میں مدد دیتے ہیں — شکریہ!"
|
|
53
|
+
nps_title: "%{app} کو بہتر بنانے میں ہماری مدد کریں"
|
|
54
|
+
nps_subtitle: "ایک مختصر سوال — دس سیکنڈ لگیں گے۔"
|
|
53
55
|
kinds:
|
|
54
56
|
text: "متن"
|
|
55
57
|
video: "ویڈیو"
|
|
@@ -57,8 +59,6 @@ ur:
|
|
|
57
59
|
widget: "ایپ کے اندر ویجیٹ"
|
|
58
60
|
page: "جمع کرنے کا صفحہ"
|
|
59
61
|
nps: "NPS فالو اپ"
|
|
60
|
-
collection_page: "تعریفی کلمات طلب کریں"
|
|
61
|
-
download_video: "ویڈیو ڈاؤن لوڈ کریں"
|
|
62
62
|
statuses:
|
|
63
63
|
pending: "زیر التوا"
|
|
64
64
|
approved: "منظور شدہ"
|
|
@@ -66,6 +66,9 @@ ur:
|
|
|
66
66
|
dashboard:
|
|
67
67
|
title: "Testimonials"
|
|
68
68
|
nps: "NPS"
|
|
69
|
+
nps_page: "NPS اسکور کی درخواست کریں"
|
|
70
|
+
collection_page: "تعریفی کلمات طلب کریں"
|
|
71
|
+
download_video: "ویڈیو ڈاؤن لوڈ کریں"
|
|
69
72
|
all_kinds: "تمام اقسام"
|
|
70
73
|
search: "تلاش"
|
|
71
74
|
search_placeholder: "متن، نام، ای میل تلاش کریں…"
|
|
@@ -50,6 +50,8 @@ vi:
|
|
|
50
50
|
page:
|
|
51
51
|
title: "Chia sẻ trải nghiệm của bạn với %{app}"
|
|
52
52
|
subtitle: "Lời của bạn giúp người khác quyết định — cảm ơn bạn!"
|
|
53
|
+
nps_title: "Giúp chúng tôi cải thiện %{app}"
|
|
54
|
+
nps_subtitle: "Một câu hỏi nhanh — chỉ mất mười giây."
|
|
53
55
|
kinds:
|
|
54
56
|
text: "Văn bản"
|
|
55
57
|
video: "Video"
|
|
@@ -57,8 +59,6 @@ vi:
|
|
|
57
59
|
widget: "Widget trong ứng dụng"
|
|
58
60
|
page: "Trang thu thập"
|
|
59
61
|
nps: "Tiếp nối NPS"
|
|
60
|
-
collection_page: "Xin cảm nhận"
|
|
61
|
-
download_video: "Tải video xuống"
|
|
62
62
|
statuses:
|
|
63
63
|
pending: "Đang chờ"
|
|
64
64
|
approved: "Đã duyệt"
|
|
@@ -66,6 +66,9 @@ vi:
|
|
|
66
66
|
dashboard:
|
|
67
67
|
title: "Testimonials"
|
|
68
68
|
nps: "NPS"
|
|
69
|
+
nps_page: "Yêu cầu điểm NPS"
|
|
70
|
+
collection_page: "Xin cảm nhận"
|
|
71
|
+
download_video: "Tải video xuống"
|
|
69
72
|
all_kinds: "Tất cả các loại"
|
|
70
73
|
search: "Tìm kiếm"
|
|
71
74
|
search_placeholder: "Tìm văn bản, tên, email…"
|
|
@@ -50,6 +50,8 @@ zh-CN:
|
|
|
50
50
|
page:
|
|
51
51
|
title: "分享您使用 %{app} 的体验"
|
|
52
52
|
subtitle: "您的评价能帮助他人做出选择——谢谢!"
|
|
53
|
+
nps_title: "帮助我们改进 %{app}"
|
|
54
|
+
nps_subtitle: "只有一个问题 — 十秒即可完成。"
|
|
53
55
|
kinds:
|
|
54
56
|
text: "文字"
|
|
55
57
|
video: "视频"
|
|
@@ -57,8 +59,6 @@ zh-CN:
|
|
|
57
59
|
widget: "应用内组件"
|
|
58
60
|
page: "收集页面"
|
|
59
61
|
nps: "NPS 跟进"
|
|
60
|
-
collection_page: "征集用户评价"
|
|
61
|
-
download_video: "下载视频"
|
|
62
62
|
statuses:
|
|
63
63
|
pending: "待处理"
|
|
64
64
|
approved: "已批准"
|
|
@@ -66,6 +66,9 @@ zh-CN:
|
|
|
66
66
|
dashboard:
|
|
67
67
|
title: "Testimonials"
|
|
68
68
|
nps: "NPS"
|
|
69
|
+
nps_page: "邀请填写 NPS"
|
|
70
|
+
collection_page: "征集用户评价"
|
|
71
|
+
download_video: "下载视频"
|
|
69
72
|
all_kinds: "所有类型"
|
|
70
73
|
search: "搜索"
|
|
71
74
|
search_placeholder: "搜索文字、姓名、邮箱…"
|
data/config/routes.rb
CHANGED
|
@@ -7,6 +7,7 @@ Testimonials::Engine.routes.draw do
|
|
|
7
7
|
get 'dashboard.js', to: 'widgets#dashboard', as: :dashboard_script
|
|
8
8
|
get 'dashboard.css', to: 'widgets#dashboard_stylesheet', as: :dashboard_stylesheet
|
|
9
9
|
get 'new', to: 'collection#show', as: :collection
|
|
10
|
+
get 'nps/new', to: 'collection#nps', as: :nps_collection
|
|
10
11
|
resources :events, only: :create
|
|
11
12
|
resource :nps, only: :create, controller: 'nps'
|
|
12
13
|
resources :nps_responses, only: %i[index show]
|
|
@@ -29,6 +29,7 @@ module Testimonials
|
|
|
29
29
|
say "\ntestimonials installed. Run `rails db:migrate`, then add", :green
|
|
30
30
|
say '`<%= testimonials_tag %>` before </body> in your layout.'
|
|
31
31
|
say 'Triage testimonials at /testimonials (development only until you set config.authorize_admin).'
|
|
32
|
+
say 'Optional: run `bin/rails testimonials:seed_demo` for sample testimonials and NPS.'
|
|
32
33
|
say "Collect from outside the app via /testimonials/new.\n"
|
|
33
34
|
end
|
|
34
35
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
namespace :testimonials do
|
|
4
|
+
desc 'Create or refresh testimonials demo data'
|
|
5
|
+
task seed_demo: :environment do
|
|
6
|
+
result = Testimonials::Seeds.load!
|
|
7
|
+
puts "Seeded #{result[:testimonials].size} testimonials, " \
|
|
8
|
+
"#{result[:nps_responses].size} NPS responses, and " \
|
|
9
|
+
"#{result[:prompt_events].size} prompt events."
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -20,6 +20,10 @@ a:hover { text-decoration: underline; }
|
|
|
20
20
|
.container { max-width: 1020px; margin: 0 auto; padding: 24px 16px 64px; }
|
|
21
21
|
h1 { font-size: 22px; margin: 0 0 16px; }
|
|
22
22
|
h1.title-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
|
23
|
+
/* Index heading row: title on the left, the shareable public link on the right. */
|
|
24
|
+
.page-head { display: flex; align-items: center; justify-content: space-between;
|
|
25
|
+
gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }
|
|
26
|
+
.page-head h1 { margin: 0; }
|
|
23
27
|
.nav { display: flex; gap: 8px; align-items: center; margin-bottom: 16px; flex-wrap: wrap; }
|
|
24
28
|
.nav a { padding: 6px 16px; border: 1px solid var(--border); border-radius: 999px;
|
|
25
29
|
background: var(--surface); color: var(--muted); font-weight: 600; }
|
|
@@ -99,9 +103,9 @@ img.avatar { width: 48px; height: 48px; border-radius: 50%; object-fit: cover; }
|
|
|
99
103
|
.tm-index, .tm-nps-index { overflow: hidden; }
|
|
100
104
|
.tm-index .container, .tm-nps-index .container { max-width: 1280px; display: flex; flex-direction: column; padding-bottom: 16px; }
|
|
101
105
|
.tm-index .nav, .tm-nps-index .nav,
|
|
102
|
-
.tm-index .container >
|
|
106
|
+
.tm-index .container > .page-head, .tm-nps-index .container > .page-head,
|
|
103
107
|
.tm-nps-index .stat-row { flex: 0 0 auto; }
|
|
104
|
-
.tm-index .container >
|
|
108
|
+
.tm-index .container > .page-head, .tm-nps-index .container > .page-head { margin-bottom: 14px; }
|
|
105
109
|
.tm-nps-index .stat-row { margin-bottom: 14px; }
|
|
106
110
|
.dashboard-shell { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: minmax(330px, 430px) 1fr;
|
|
107
111
|
gap: 16px; }
|
|
Binary file
|
data/lib/testimonials/engine.rb
CHANGED
|
@@ -4,6 +4,10 @@ module Testimonials
|
|
|
4
4
|
class Engine < ::Rails::Engine
|
|
5
5
|
isolate_namespace Testimonials
|
|
6
6
|
|
|
7
|
+
rake_tasks do
|
|
8
|
+
load File.expand_path('../tasks/testimonials_tasks.rake', __dir__)
|
|
9
|
+
end
|
|
10
|
+
|
|
7
11
|
initializer 'testimonials.helpers' do
|
|
8
12
|
ActiveSupport.on_load(:action_view) do
|
|
9
13
|
include Testimonials::WidgetHelper
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Testimonials
|
|
4
|
+
module Seeds
|
|
5
|
+
VIDEO_PATH = File.expand_path('demo/flower.mp4', __dir__)
|
|
6
|
+
|
|
7
|
+
TESTIMONIALS = [
|
|
8
|
+
{
|
|
9
|
+
seed_id: 'approved-founder',
|
|
10
|
+
kind: 'text',
|
|
11
|
+
body: 'We added the widget after onboarding and collected better customer quotes in the first week.',
|
|
12
|
+
best_line: 'Collected better customer quotes in the first week.',
|
|
13
|
+
rating: 5,
|
|
14
|
+
status: 'approved',
|
|
15
|
+
featured: true,
|
|
16
|
+
consent_given: true,
|
|
17
|
+
consent_text: 'You can use my testimonial publicly in your marketing and sales.',
|
|
18
|
+
name: 'Maya Chen',
|
|
19
|
+
email: 'maya@example.com',
|
|
20
|
+
title_company: 'Founder, DemoCRM',
|
|
21
|
+
source: 'widget',
|
|
22
|
+
page_url: '/onboarding/complete',
|
|
23
|
+
locale: 'en'
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
seed_id: 'pending-operator',
|
|
27
|
+
kind: 'text',
|
|
28
|
+
body: 'The NPS prompt felt lightweight and did not interrupt the workflow.',
|
|
29
|
+
rating: 4,
|
|
30
|
+
status: 'pending',
|
|
31
|
+
featured: false,
|
|
32
|
+
consent_given: true,
|
|
33
|
+
consent_text: 'You can use my testimonial publicly in your marketing and sales.',
|
|
34
|
+
name: 'Jon Bell',
|
|
35
|
+
email: 'jon@example.com',
|
|
36
|
+
title_company: 'Operations Lead, ExampleCo',
|
|
37
|
+
source: 'nps',
|
|
38
|
+
page_url: '/reports',
|
|
39
|
+
locale: 'en'
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
seed_id: 'private-archive',
|
|
43
|
+
kind: 'text',
|
|
44
|
+
body: 'Useful for our internal rollout notes, but please do not publish my name.',
|
|
45
|
+
rating: 3,
|
|
46
|
+
status: 'archived',
|
|
47
|
+
featured: false,
|
|
48
|
+
consent_given: false,
|
|
49
|
+
consent_text: 'You can only use my testimonial privately in your marketing and sales.',
|
|
50
|
+
name: 'Priya Rao',
|
|
51
|
+
email: 'priya@example.com',
|
|
52
|
+
title_company: 'Customer Success, SampleOps',
|
|
53
|
+
source: 'page',
|
|
54
|
+
page_url: '/testimonials/new',
|
|
55
|
+
locale: 'en'
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
seed_id: 'approved-video',
|
|
59
|
+
kind: 'video',
|
|
60
|
+
body: 'Short demo video testimonial with a real MP4 attachment.',
|
|
61
|
+
best_line: 'A real video testimonial is ready to review.',
|
|
62
|
+
rating: 5,
|
|
63
|
+
status: 'approved',
|
|
64
|
+
featured: true,
|
|
65
|
+
consent_given: true,
|
|
66
|
+
consent_text: 'You can use my testimonial publicly in your marketing and sales.',
|
|
67
|
+
name: 'Alex Rivera',
|
|
68
|
+
email: 'alex@example.com',
|
|
69
|
+
title_company: 'Head of Product, VideoDemo',
|
|
70
|
+
source: 'page',
|
|
71
|
+
page_url: '/testimonials/new',
|
|
72
|
+
locale: 'en'
|
|
73
|
+
}
|
|
74
|
+
].freeze
|
|
75
|
+
|
|
76
|
+
NPS_RESPONSES = [
|
|
77
|
+
{ seed_id: 'promoter', score: 10,
|
|
78
|
+
comment: 'Fast to install and easy to trust because the data stays in our app.' },
|
|
79
|
+
{ seed_id: 'passive', score: 8, comment: 'The flow is useful, but I would like more display examples.' },
|
|
80
|
+
{ seed_id: 'detractor', score: 4, comment: 'I was not sure when the prompt would appear again.' }
|
|
81
|
+
].freeze
|
|
82
|
+
|
|
83
|
+
PROMPT_EVENTS = [
|
|
84
|
+
{ kind: 'testimonial', action: 'shown', visitor_token: 'testimonials-demo-visitor' },
|
|
85
|
+
{ kind: 'testimonial', action: 'dismissed', visitor_token: 'testimonials-demo-visitor' },
|
|
86
|
+
{ kind: 'nps', action: 'submitted', author_id: 'testimonials-demo:nps-promoter' }
|
|
87
|
+
].freeze
|
|
88
|
+
|
|
89
|
+
def self.load!(tenant: nil)
|
|
90
|
+
{
|
|
91
|
+
testimonials: load_testimonials!(tenant: tenant),
|
|
92
|
+
nps_responses: load_nps_responses!(tenant: tenant),
|
|
93
|
+
prompt_events: load_prompt_events!(tenant: tenant)
|
|
94
|
+
}
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def self.load_testimonials!(tenant:)
|
|
98
|
+
TESTIMONIALS.map do |attributes|
|
|
99
|
+
seed_id = attributes.fetch(:seed_id)
|
|
100
|
+
testimonial = Testimonials::Testimonial.find_or_initialize_by(
|
|
101
|
+
author_id: "testimonials-demo:#{seed_id}",
|
|
102
|
+
tenant: tenant.presence
|
|
103
|
+
)
|
|
104
|
+
testimonial.assign_attributes(
|
|
105
|
+
attributes.except(:seed_id).merge(tenant: tenant.presence, user_agent: 'testimonials demo seed')
|
|
106
|
+
)
|
|
107
|
+
testimonial.save!
|
|
108
|
+
attach_demo_video!(testimonial) if seed_id == 'approved-video'
|
|
109
|
+
testimonial
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
private_class_method :load_testimonials!
|
|
113
|
+
|
|
114
|
+
def self.load_nps_responses!(tenant:)
|
|
115
|
+
NPS_RESPONSES.map do |attributes|
|
|
116
|
+
seed_id = attributes.fetch(:seed_id)
|
|
117
|
+
response = Testimonials::NpsResponse.find_or_initialize_by(
|
|
118
|
+
author_id: "testimonials-demo:nps-#{seed_id}",
|
|
119
|
+
tenant: tenant.presence
|
|
120
|
+
)
|
|
121
|
+
response.assign_attributes(
|
|
122
|
+
attributes.except(:seed_id).merge(
|
|
123
|
+
name: 'Demo Respondent',
|
|
124
|
+
email: "#{seed_id}@example.com",
|
|
125
|
+
page_url: '/dashboard',
|
|
126
|
+
user_agent: 'testimonials demo seed',
|
|
127
|
+
locale: 'en',
|
|
128
|
+
tenant: tenant.presence
|
|
129
|
+
)
|
|
130
|
+
)
|
|
131
|
+
response.save!
|
|
132
|
+
response
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
private_class_method :load_nps_responses!
|
|
136
|
+
|
|
137
|
+
def self.load_prompt_events!(tenant:)
|
|
138
|
+
PROMPT_EVENTS.map do |attributes|
|
|
139
|
+
event = Testimonials::PromptEvent.find_or_initialize_by(
|
|
140
|
+
attributes.slice(:kind, :action, :author_id, :visitor_token).merge(tenant: tenant.presence)
|
|
141
|
+
)
|
|
142
|
+
event.save!
|
|
143
|
+
event
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
private_class_method :load_prompt_events!
|
|
147
|
+
|
|
148
|
+
def self.attach_demo_video!(testimonial)
|
|
149
|
+
return unless Testimonials.config.video_enabled?
|
|
150
|
+
return unless testimonial.respond_to?(:video_file)
|
|
151
|
+
return if testimonial.video_file.attached?
|
|
152
|
+
return unless File.exist?(VIDEO_PATH)
|
|
153
|
+
|
|
154
|
+
File.open(VIDEO_PATH, 'rb') do |file|
|
|
155
|
+
testimonial.video_file.attach(
|
|
156
|
+
io: file,
|
|
157
|
+
filename: 'testimonials-demo-flower.mp4',
|
|
158
|
+
content_type: 'video/mp4'
|
|
159
|
+
)
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
private_class_method :attach_demo_video!
|
|
163
|
+
end
|
|
164
|
+
end
|
data/lib/testimonials/version.rb
CHANGED