main
tag: launch-2026-06-01
tag: magicmirror-v0.1.1
tag: magicmirror-v0.3.0
tag: mnw-cli-v0.1.2
tag: mnw-cli-v0.1.3
tag: mnw-cli-v0.1.4
tag: pom-v0.4.1
tag: pom-v0.4.2
tag: pom-v0.4.3
tag: pom-v0.4.4
tag: pom-v0.4.5
tag: wam-v0.3.0
tag: wam-v0.3.1
Files
Commits
Tags
Notes
Issues
Switch price inputs from cents to dollars
All creator-facing price inputs now accept dollar values with
auto-conversion to cents via hidden fields:
- PWYW minimum price (item pricing tab)
- Subscription tier monthly price (project subscriptions tab)
- Promo code fixed discount (project promotions tab)
- Inline item price edit (item edit row)
Co-Authored-By
Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5 files changed,
+60 insertions,
-14 deletions
38
38
### High (significant friction reduction)
39
39
40
40
- [ ] **[MEDIUM]** Restructure user dashboard tabs — show 4 core tabs (Account, Projects, Payments, Support) by default. Collapse SyncKit, SSH Keys, Forums, Media into "More Tools" overflow section. Current 11 tabs overwhelm new creators
41
-
- [ ] **[MEDIUM]** Fix price input to use dollars, not cents — promo code and subscription tier forms accept cents (e.g. "500" for $5). Add live preview ("= $5.00") or switch to dollar input with auto-conversion
41
+
- [x] **[MEDIUM]** Fix price input to use dollars, not cents — PWYW min, subscription tier, promo code fixed discount, and inline item edit all now accept dollars with auto-conversion to cents
42
42
- [x] **[MEDIUM]** Standardize pricing terminology — item wizard now says "One-Time Purchase" to match project wizard, paywall, landing page, and docs
43
43
- [x] **[MEDIUM]** Add self-service refund UI for creators — new "Sales" tab on item dashboard with per-transaction refund buttons, Stripe refund API integration
44
44
13
13
</select>
14
14
</td>
15
15
<td>
16
-
<input type="number" name="price_cents" value="" placeholder="0" class="edit-input" style="width: 80px;">
16
+
<input type="number" step="0.01" min="0" placeholder="0.00" class="edit-input" style="width: 80px;"
17
+
oninput="this.nextElementSibling.value = Math.round(parseFloat(this.value || 0) * 100)">
18
+
<input type="hidden" name="price_cents" value="0">
17
19
</td>
18
20
<td>{{ item.sales }}</td>
19
21
<td>{{ item.revenue }}</td>
21
21
22
22
<div id="pwyw-settings" style="{% if !item.pwyw_enabled %}display: none;{% endif %}">
23
23
<div class="form-group">
24
-
<label for="pwyw-min">Minimum price (cents)</label>
25
-
<input type="number" id="pwyw-min" name="pwyw_min_cents"
26
-
value="{% if let Some(min) = item.pwyw_min_cents %}{{ min }}{% endif %}"
27
-
min="0" placeholder="0 (any amount)">
28
-
<p class="form-hint">The lowest amount a buyer can pay, in cents. 0 = any amount.</p>
24
+
<label for="pwyw-min-dollars">Minimum price ($)</label>
25
+
<input type="number" id="pwyw-min-dollars" step="0.01" min="0" placeholder="0.00">
26
+
<input type="hidden" id="pwyw-min-cents" name="pwyw_min_cents"
27
+
value="{% if let Some(min) = item.pwyw_min_cents %}{{ min }}{% endif %}">
28
+
<p class="form-hint">The lowest amount a buyer can pay. $0 = any amount.</p>
29
29
</div>
30
30
</div>
31
+
<script>
32
+
(function() {
33
+
var dollars = document.getElementById('pwyw-min-dollars');
34
+
var cents = document.getElementById('pwyw-min-cents');
35
+
if (cents.value) dollars.value = (parseInt(cents.value, 10) / 100).toFixed(2);
36
+
dollars.addEventListener('input', function() {
37
+
cents.value = Math.round(parseFloat(this.value || 0) * 100);
38
+
});
39
+
})();
40
+
</script>
31
41
32
42
<button class="primary" type="submit">
33
43
Save PWYW Settings
38
38
</select>
39
39
</div>
40
40
<div class="form-group" style="margin-bottom: 0;">
41
-
<label for="pc-value" style="font-size: 0.85rem;">Value</label>
42
-
<input type="number" id="pc-value" name="discount_value" min="1"
41
+
<label for="pc-value-input" style="font-size: 0.85rem;">Value</label>
42
+
<input type="number" id="pc-value-input" min="1" step="1"
43
43
placeholder="e.g. 50" style="width: 100px;">
44
+
<input type="hidden" id="pc-value-hidden" name="discount_value">
44
45
</div>
45
46
</div>
46
47
<div id="trial-fields" class="form-group" style="margin-bottom: 0; display: none;">
70
71
{% endif %}
71
72
<button class="secondary" type="submit" style="height: fit-content;">Create</button>
72
73
</div>
73
-
<p class="form-hint" style="margin-top: 0.5rem;">For percentage: enter 1-100. For fixed: enter amount in cents (e.g. 500 = $5.00). Free access codes auto-generate if left blank.</p>
74
+
<p class="form-hint" style="margin-top: 0.5rem;">For percentage: enter 1-100. For fixed: enter dollar amount (e.g. 5 = $5.00 off). Free access codes auto-generate if left blank.</p>
75
+
<script>
76
+
(function() {
77
+
var typeSelect = document.getElementById('pc-type');
78
+
var input = document.getElementById('pc-value-input');
79
+
var hidden = document.getElementById('pc-value-hidden');
80
+
function updatePromoInput() {
81
+
if (typeSelect.value === 'fixed') {
82
+
input.step = '0.01';
83
+
input.placeholder = 'e.g. 5.00';
84
+
} else {
85
+
input.step = '1';
86
+
input.placeholder = 'e.g. 50';
87
+
}
88
+
syncValue();
89
+
}
90
+
function syncValue() {
91
+
var val = parseFloat(input.value || 0);
92
+
hidden.value = typeSelect.value === 'fixed' ? Math.round(val * 100) : Math.round(val);
93
+
}
94
+
typeSelect.addEventListener('change', updatePromoInput);
95
+
input.addEventListener('input', syncValue);
96
+
updatePromoInput();
97
+
})();
98
+
</script>
74
99
</form>
75
100
</details>
76
101
28
28
<textarea id="tier-description" name="description" placeholder="What subscribers get..." maxlength="2000"></textarea>
29
29
</div>
30
30
<div class="form-group">
31
-
<label for="tier-price">Monthly Price (USD)</label>
32
-
<input type="number" id="tier-price" name="price_cents" min="100" step="1" placeholder="500" required
33
-
title="Price in cents (e.g. 500 = $5.00)">
34
-
<span style="font-size: 0.85rem; opacity: 0.6;">In cents. Minimum $1.00 (100 cents).</span>
31
+
<label for="tier-price-dollars">Monthly Price ($)</label>
32
+
<input type="number" id="tier-price-dollars" step="0.01" min="1.00" placeholder="5.00" required>
33
+
<input type="hidden" id="tier-price-cents" name="price_cents">
34
+
<span style="font-size: 0.85rem; opacity: 0.6;">Minimum $1.00.</span>
35
35
</div>
36
+
<script>
37
+
(function() {
38
+
var dollars = document.getElementById('tier-price-dollars');
39
+
var cents = document.getElementById('tier-price-cents');
40
+
dollars.addEventListener('input', function() {
41
+
cents.value = Math.round(parseFloat(this.value || 0) * 100);
42
+
});
43
+
})();
44
+
</script>
36
45
<button class="primary" type="submit">Create Tier</button>
37
46
</form>
38
47
</details>