Skip to main content

max / makenotwork

6.8 KB · 147 lines History Blame Raw
1 <div class="pricing-strategies">
2 <div class="pricing-strategies-title">Pricing strategies</div>
3 <div class="pricing-strategies-grid">
4 <div><strong>Fixed price</strong>: set in the Details tab. Good for finished products.</div>
5 <div><strong>Pay What You Want</strong>: fans choose their price. Set a minimum below.</div>
6 <div><strong>Free + promo codes</strong>: set price to $0, then generate codes for specific access.</div>
7 <div><strong>License keys</strong>: per-seat licensing for software. Works with any pricing model.</div>
8 </div>
9 </div>
10
11 <!-- Pay What You Want -->
12 <div class="content-section raised">
13 <div class="section-header">
14 <h2 class="subsection-title">Pay What You Want</h2>
15 </div>
16
17 <form hx-put="/api/items/{{ item.id }}"
18 hx-target="#pwyw-save-status"
19 hx-swap="innerHTML"
20 hx-indicator="#pwyw-spinner">
21 <div class="form-group">
22 <label class="checkbox-label">
23 <input type="hidden" name="pwyw_enabled" value="off">
24 <input type="checkbox" name="pwyw_enabled" value="on"
25 {% if item.pwyw_enabled %}checked{% endif %}
26 data-change="togglePwywSettings">
27 Enable pay-what-you-want pricing
28 </label>
29 <p class="form-hint">The item price becomes the suggested amount. Buyers can choose any amount at or above the minimum.</p>
30 </div>
31
32 <div id="pwyw-settings"{% if !item.pwyw_enabled %} class="hidden"{% endif %}>
33 <div class="form-group">
34 <label for="pwyw-min-dollars">Minimum price</label>
35 <input type="number" id="pwyw-min-dollars" step="0.01" min="0" placeholder="0.00"
36 aria-describedby="pwyw-min-dollars-unit">
37 <span class="form-unit" id="pwyw-min-dollars-unit">USD</span>
38 <input type="hidden" id="pwyw-min-cents" name="pwyw_min_cents"
39 value="{% if let Some(min) = item.pwyw_min_cents %}{{ min }}{% endif %}">
40 <p class="form-hint">The lowest amount a buyer can pay. $0 = any amount.</p>
41 </div>
42 </div>
43 <script src="/static/tab-item-pricing.js?v=0623"></script>
44
45 <button class="btn-primary" type="submit">
46 Save PWYW Settings
47 <span id="pwyw-spinner" class="htmx-indicator"> ...</span>
48 </button>
49 <span id="pwyw-save-status"></span>
50 </form>
51 </div>
52
53 <!-- License Terms -->
54 <div class="content-section raised">
55 <div class="section-header">
56 <h2 class="subsection-title">License Terms</h2>
57 </div>
58
59 <form hx-put="/api/items/{{ item.id }}/license-settings"
60 hx-target="#license-save-status"
61 hx-swap="innerHTML"
62 hx-indicator="#license-spinner">
63 <div class="form-group">
64 <label for="dash-license-preset">License</label>
65 <select id="dash-license-preset" name="license_preset"
66 data-change="toggleCustomLicense">
67 <option value="">None (no license)</option>
68 {% for opt in license_preset_options %}
69 <option value="{{ opt.0 }}"{% if item.license_preset.as_deref() == Some(opt.0) %} selected{% endif %}>{{ opt.1 }}</option>
70 {% endfor %}
71 </select>
72 <p class="form-hint">Displayed on the item page and included with downloads as LICENSE.txt.</p>
73 </div>
74
75 <div id="dash-custom-license"{% if item.license_preset.as_deref() != Some("custom") %} class="hidden"{% endif %}>
76 <div class="form-group">
77 <label for="dash-custom-text">Custom License Text</label>
78 <textarea id="dash-custom-text" name="custom_license_text" rows="6"
79 placeholder="Enter your custom license terms...">{{ item.custom_license_text.as_deref().unwrap_or("") }}</textarea>
80 </div>
81 </div>
82
83 <div class="form-group">
84 <label class="checkbox-label">
85 <input type="checkbox" name="enable_license_keys" value="on"
86 {% if item.enable_license_keys %}checked{% endif %}
87 data-change="toggleLicenseKeys">
88 Enable license keys for this item
89 </label>
90 <p class="form-hint">Buyers receive a unique license key with their purchase. Each key can be activated on a limited number of devices (you choose). Useful for software with per-seat licensing. Works with any pricing model including Pay What You Want.</p>
91 </div>
92
93 <div class="form-group">
94 <label for="default-max-activations">Default max activations per key</label>
95 <input type="number" id="default-max-activations" name="default_max_activations"
96 value="{% if let Some(max) = item.default_max_activations %}{{ max }}{% endif %}"
97 min="1" placeholder="Leave blank for unlimited">
98 <p class="form-hint">How many machines can activate each key. Blank = unlimited.</p>
99 </div>
100
101 <button class="btn-primary" type="submit">
102 Save License Settings
103 <span id="license-spinner" class="htmx-indicator"> ...</span>
104 </button>
105 <span id="license-save-status"></span>
106 </form>
107
108 <div id="license-keys-section" class="license-keys-section{% if !item.enable_license_keys %} hidden{% endif %}">
109 <div class="section-header">
110 <h3>Generated Keys</h3>
111 <form hx-post="/api/items/{{ item.id }}/keys"
112 hx-target="#license-keys-list"
113 hx-swap="outerHTML">
114 <button class="btn-secondary" type="submit">Generate Key</button>
115 </form>
116 </div>
117
118 {% include "partials/item_license_keys.html" %}
119 </div>
120 </div>
121
122 <!-- Promo Codes -->
123 <div class="content-section raised">
124 <div class="section-header">
125 <h2 class="subsection-title">Promo Codes</h2>
126 </div>
127 <p class="form-hint promo-codes-hint">Generate codes that grant free access to this item. Share them with reviewers, collaborators, or for promotions.</p>
128
129 <form hx-post="/api/promo-codes"
130 hx-target="#promo-codes-list"
131 hx-swap="outerHTML"
132 class="promo-codes-form">
133 <input type="hidden" name="item_id" value="{{ item.id }}">
134 <input type="hidden" name="code_purpose" value="free_access">
135 <div class="promo-codes-row">
136 <input type="number" name="max_uses" min="1" placeholder="Max uses (blank = unlimited)"
137 class="promo-max-uses">
138 <input type="date" name="expires_at" placeholder="Expires (optional)"
139 title="Expiry date (optional)"
140 class="promo-expires">
141 <button class="btn-secondary" type="submit">Generate Code</button>
142 </div>
143 </form>
144
145 {% include "partials/promo_codes_list.html" %}
146 </div>
147