testimonials 0.9.0 → 0.9.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b79e1e2893951f81ee3c7144fd2c2eaba89d6b6753e75b243b7ec961aa5ec39b
4
- data.tar.gz: c55a34d075dfa5604b302a21a3c75d317fcef8253420799a343b64878b8fb65f
3
+ metadata.gz: 0cbc7f22314c712ecb0e1eb5d92a3d66981193bc1fc19f8664f635d381db0045
4
+ data.tar.gz: '020981c67a45702104ebf9cdfd9f685ffc17d44653a3476560c0fb662176e445'
5
5
  SHA512:
6
- metadata.gz: 6fb8c825f96b096352a4f181de4b6da669bead079925461b0cff538ee79cbd31d77917a834c07abf621e4f7a49835c66740b84b175ebb0575f522692f1e8e91c
7
- data.tar.gz: 8f28f17a353aa422e90fed7949f9cd991bf5d47f60e8d396cd4f4086e21daa0da4dd2c11d4ba521a5cbf6429c139303db99e52c32dcc969ea49d037576e5f69c
6
+ metadata.gz: 1ca4a49fd102d401ae88b344c951655e68e88af3fb0da1a11819b7b600edb9ad11543feb5440a25f2127e138f4da54d9d7447a3b260a79d7e3cb59b5abcdbfb2
7
+ data.tar.gz: d8c94fe02b56b3e91adf3eb39e1c87e88b70d4f0d9ed4102e8058901b019f0a1c5fb4d1d02327be255c18b5ca58afedae06e7386efd58978d16d017fde1bc8d5
data/AGENTS.md CHANGED
@@ -210,6 +210,6 @@ Conventions this codebase holds to — follow them rather than the first thing t
210
210
  - **Every install shape gets a test that drops the table for real** (`test/integration/skip_nps_test.rb`, `skip_prompt_events_test.rb`), so a slipped guard raises `no such table` instead of passing quietly. Generator tests pin each migration and initializer shape and check the ERB still compiles as Ruby.
211
211
  - **The widget is plain ES5-style JS in `lib/testimonials/widget.js`**, served by the engine, no build step, no framework. It reads its config from a JSON block on every `turbo:load`.
212
212
  - **Display stays headless.** New display UI belongs in `examples/`, not in `app/views`.
213
- - **`lib/testimonials/dashboard.css` is half shared.** Everything above the `GEM-SPECIFIC` banner is the design system all five gems in the family ship — the same tokens, the same `.page-head`/`.tabs`/`.filters`/`.card`/`.badge`/`button`, the same `.dashboard-shell` + `.record-row` + `.detail-panel` two-pane dashboard — identical in every repo apart from the `tml` prefix. Diff it against a sibling before changing it, and carry the change to the other four. Anything only this gem has goes below the banner. New dashboard markup reuses the shared class names rather than inventing a domain-specific one.
213
+ - **`lib/testimonials/dashboard.css` is half shared.** Everything above the `GEM-SPECIFIC` banner is the design system all five gems in the family ship — the same tokens, the same `.page-head`/`.tabs`/`.filters`/`.card`/`.badge`/`button`/`.status-switch`, the same `.dashboard-shell` + `.record-row` + `.detail-panel` two-pane dashboard — identical in every repo apart from the `tml` prefix. Diff it against a sibling before changing it, and carry the change to the other four. Anything only this gem has goes below the banner. New dashboard markup reuses the shared class names rather than inventing a domain-specific one.
214
214
  - Every user-facing change bumps `lib/testimonials/version.rb` and adds a `CHANGELOG.md` entry that says what it costs, not only what it adds.
215
215
  - Commit messages are prose that explains the tradeoff — read `git log` before writing one.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.9.1
4
+
5
+ - **The demo data now teaches responsible collection.** Its testimonials cover
6
+ success-moment prompting, pending moderation, public consent, private
7
+ archiving, best lines, and the shared approval rules for text and video. The
8
+ promoter, passive, and detractor comments explain why the balanced sample has
9
+ an NPS of zero.
10
+ - The bundled video remains intentionally generic: it proves protected upload
11
+ and playback without pretending to be customer evidence. Rerunning
12
+ `testimonials:seed_demo` refreshes the existing demo rows and can overwrite
13
+ edits to them; non-demo customer records are not touched.
14
+
3
15
  ## 0.9.0
4
16
 
5
17
  - **One design system across the family.** The stylesheet now opens with a
@@ -144,6 +144,19 @@
144
144
  & .actions form { display: inline; }
145
145
  & .form-actions { padding-top: 12px; }
146
146
 
147
+ /* Status switch: one pill holding every state a record can be in, the state it
148
+ is in now lit. Each other segment is a submit button, so moving a record
149
+ takes one click and no JavaScript; the current segment is a `type="button"`
150
+ so clicking it cannot re-file the record it is already filed under. Two
151
+ states or five, the pill sizes itself. A gem tints the lit segment with its
152
+ own status colour — see the `GEM-SPECIFIC` section. */
153
+ & .status-switch { display: inline-flex; flex: 0 0 auto; margin: 0; padding: 3px; border: 1px solid var(--tml-border); border-radius: 999px; background: var(--tml-bg); }
154
+ & .status-switch button { min-height: 30px; padding: 0 12px; border: 0; border-radius: 999px; background: none; color: var(--tml-muted); font-size: 13px; font-weight: 700; white-space: nowrap; transition: background .16s ease, color .16s ease; }
155
+ & .status-switch button:hover { border: 0; background: color-mix(in srgb, var(--tml-muted) 12%, transparent); color: var(--tml-text); }
156
+ & .status-switch button.current { background: var(--tml-surface); color: var(--tml-text); box-shadow: 0 1px 2px rgba(15, 23, 42, .12); cursor: default; }
157
+ & .status-switch button.current:hover { background: var(--tml-surface); }
158
+ & .panel-head .status-switch { margin-left: auto; }
159
+
147
160
  & .card { overflow: hidden; border: 1px solid var(--tml-border); border-radius: 12px; background: var(--tml-surface); }
148
161
  & .card.pad { padding: 16px; overflow: visible; }
149
162
  & table { width: 100%; border-collapse: collapse; }
@@ -266,6 +279,7 @@
266
279
  & .dashboard-detail .detail-panel { min-height: calc(100vh - 64px); }
267
280
  & .mobile-back { display: block; flex: 0 0 auto; margin: 4px 0 10px; font-size: 13px; }
268
281
  & .panel-head h1 { font-size: 18px; }
282
+ & .status-switch button { padding: 0 9px; font-size: 12px; }
269
283
  & dl { grid-template-columns: 1fr; gap: 3px; }
270
284
  & dd { margin-bottom: 8px; }
271
285
  }
@@ -9,8 +9,10 @@ module Testimonials
9
9
  {
10
10
  seed_id: 'approved-founder',
11
11
  kind: 'text',
12
- body: 'We added the widget after onboarding and collected better customer quotes in the first week.',
13
- best_line: 'Collected better customer quotes in the first week.',
12
+ body: 'We call testimonial_prompt! after a customer completes onboarding, when the value is still ' \
13
+ 'fresh. The prompt feels earned, and the quotes are much more specific than the ones we used ' \
14
+ 'to request by email.',
15
+ best_line: 'Ask after a real success moment and the quotes become specific.',
14
16
  rating: 5,
15
17
  status: 'approved',
16
18
  featured: true,
@@ -18,7 +20,7 @@ module Testimonials
18
20
  consent_text: 'You can use my testimonial publicly in your marketing and sales.',
19
21
  name: 'Maya Chen',
20
22
  email: 'maya@example.com',
21
- title_company: 'Founder, DemoCRM',
23
+ title_company: 'Founder, Demo CRM',
22
24
  source: 'widget',
23
25
  page_url: '/onboarding/complete',
24
26
  locale: 'en'
@@ -26,7 +28,9 @@ module Testimonials
26
28
  {
27
29
  seed_id: 'pending-operator',
28
30
  kind: 'text',
29
- body: 'The NPS prompt felt lightweight and did not interrupt the workflow.',
31
+ body: 'This response has public consent, but it is still pending. That separation gives our team a ' \
32
+ 'chance to verify the quote, choose a best line, and approve it before anything appears on the ' \
33
+ 'wall of love.',
30
34
  rating: 4,
31
35
  status: 'pending',
32
36
  featured: false,
@@ -34,7 +38,7 @@ module Testimonials
34
38
  consent_text: 'You can use my testimonial publicly in your marketing and sales.',
35
39
  name: 'Jon Bell',
36
40
  email: 'jon@example.com',
37
- title_company: 'Operations Lead, ExampleCo',
41
+ title_company: 'Operations Lead, Example Co',
38
42
  source: 'nps',
39
43
  page_url: '/reports',
40
44
  locale: 'en'
@@ -42,7 +46,8 @@ module Testimonials
42
46
  {
43
47
  seed_id: 'private-archive',
44
48
  kind: 'text',
45
- body: 'Useful for our internal rollout notes, but please do not publish my name.',
49
+ body: 'I am happy for the team to keep this feedback internally, but I did not consent to public ' \
50
+ 'use. Archiving it keeps the learning without making it publishable.',
46
51
  rating: 3,
47
52
  status: 'archived',
48
53
  featured: false,
@@ -58,8 +63,10 @@ module Testimonials
58
63
  {
59
64
  seed_id: 'approved-video',
60
65
  kind: 'video',
61
- body: 'Short demo video testimonial with a real MP4 attachment.',
62
- best_line: 'A real video testimonial is ready to review.',
66
+ body: 'The attached clip is intentionally generic demo media. It proves the upload, review, and ' \
67
+ 'protected playback path; replace it with a real customer recording before using this record ' \
68
+ 'anywhere public.',
69
+ best_line: 'Video follows the same consent and approval workflow as text.',
63
70
  rating: 5,
64
71
  status: 'approved',
65
72
  featured: true,
@@ -67,7 +74,7 @@ module Testimonials
67
74
  consent_text: 'You can use my testimonial publicly in your marketing and sales.',
68
75
  name: 'Alex Rivera',
69
76
  email: 'alex@example.com',
70
- title_company: 'Head of Product, VideoDemo',
77
+ title_company: 'Head of Product, Demo Video Co',
71
78
  source: 'page',
72
79
  page_url: '/testimonials/new',
73
80
  locale: 'en'
@@ -76,9 +83,12 @@ module Testimonials
76
83
 
77
84
  NPS_RESPONSES = [
78
85
  { seed_id: 'promoter', score: 10,
79
- comment: 'Fast to install and easy to trust because the data stays in our app.' },
80
- { seed_id: 'passive', score: 8, comment: 'The flow is useful, but I would like more display examples.' },
81
- { seed_id: 'detractor', score: 4, comment: 'I was not sure when the prompt would appear again.' }
86
+ comment: 'A 9 or 10 is a promoter. One promoter contributes positively to the NPS score.' },
87
+ { seed_id: 'passive', score: 8,
88
+ comment: 'A 7 or 8 is passive. Keep the feedback, but this response does not move the NPS score.' },
89
+ { seed_id: 'detractor', score: 4,
90
+ comment: 'A score from 0 to 6 is a detractor. With one promoter and one detractor, this demo board ' \
91
+ 'totals 0 NPS.' }
82
92
  ].freeze
83
93
 
84
94
  PROMPT_EVENTS = [
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Testimonials
4
- VERSION = '0.9.0'
4
+ VERSION = '0.9.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: testimonials
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yaroslav Shmarov
@@ -152,7 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
152
  - !ruby/object:Gem::Version
153
153
  version: '0'
154
154
  requirements: []
155
- rubygems_version: 3.6.9
155
+ rubygems_version: 4.0.10
156
156
  specification_version: 4
157
157
  summary: 'Testimonials, reviews and NPS for Rails: in-app collection widget, public
158
158
  collection page, triage dashboard, and a read API.'