Skip to main content

max / makenotwork

12.2 KB · 283 lines History Blame Raw
1 <div class="tab-docs"><a href="/docs/pricing">Docs: Pricing &rarr;</a></div>
2
3 {% if can_create_projects %}
4 {% if user.stripe_connected %}
5 <!-- Stripe Account Status -->
6 <div class="stripe-status-box card-muted mb-5">
7 <div class="stack-row">
8 <div class="stack-row stack-row--tight">
9 {% if user.stripe_onboarding_complete && user.stripe_charges_enabled && user.stripe_payouts_enabled %}
10 <span class="badge badge-success">Ready</span>
11 <div>
12 <div class="fw-bold">Ready to receive payments</div>
13 <div class="text-xs dimmed">Stripe is fully configured</div>
14 </div>
15 {% else if !user.stripe_onboarding_complete %}
16 <span class="warn-glyph">!</span>
17 <div>
18 <div class="fw-bold">Action required: Complete Stripe setup</div>
19 <div class="text-xs dimmed">Provide identity verification, business details, and bank account</div>
20 </div>
21 {% else if !user.stripe_charges_enabled %}
22 <span class="warn-glyph">!</span>
23 <div>
24 <div class="fw-bold">Pending: Stripe is reviewing your account</div>
25 <div class="text-xs dimmed">Charges will be enabled within 1-2 business days</div>
26 </div>
27 {% else %}
28 <span class="warn-glyph">!</span>
29 <div>
30 <div class="fw-bold">Action required: Verify bank account</div>
31 <div class="text-xs dimmed">Set up payouts in your Stripe settings</div>
32 </div>
33 {% endif %}
34 </div>
35 {% if !user.stripe_onboarding_complete %}
36 <a href="/stripe/connect">
37 <button class="btn-primary text-sm">Complete Setup</button>
38 </a>
39 {% else %}
40 <a href="https://dashboard.stripe.com" target="_blank" rel="noopener">
41 <button class="btn-secondary text-sm">Stripe Dashboard</button>
42 </a>
43 {% endif %}
44 </div>
45
46 {% if let Some(account_id) = user.stripe_account_id %}
47 <details class="account-details">
48 <summary class="text-xs dimmer">Account details</summary>
49 <div class="account-details-id">{{ account_id }}</div>
50 </details>
51 {% endif %}
52 </div>
53
54 <div class="stripe-actions mb-5">
55 <a href="https://dashboard.stripe.com/payouts" target="_blank" rel="noopener">
56 <button class="btn-secondary">View Payouts</button>
57 </a>
58 <a href="https://dashboard.stripe.com/settings/payouts" target="_blank" rel="noopener">
59 <button class="btn-secondary">Manage Bank Account</button>
60 </a>
61 <button class="btn-danger stripe-actions-disconnect"
62 hx-delete="/api/users/me/stripe"
63 hx-confirm="Disconnect your Stripe account? You won't be able to receive payments until you reconnect."
64 data-hx-click="tab-payments">
65 Disconnect Stripe
66 </button>
67 </div>
68
69 <div class="section-group-label">Payouts</div>
70
71 {% if user.stripe_account_id.is_some() %}
72 <!-- Stripe balance is lazy-loaded so the tab render never blocks on the
73 Stripe round-trip (ultra-fuzz Run 11 Perf SER-2). -->
74 <div hx-get="/dashboard/tabs/payout-summary" hx-trigger="revealed" hx-swap="innerHTML" id="payout-summary-section">
75 <div class="card-muted mb-5">
76 <h3 class="card-h">Payout Summary</h3>
77 <p class="m-0 text-sm muted">Loading balance.</p>
78 </div>
79 </div>
80 {% endif %}
81
82 <div class="section-group-label">Settings</div>
83
84 <details class="form-section">
85 <summary><h2 class="subsection-title">Payment Settings</h2></summary>
86 <div class="card-muted mb-5">
87 <h3 class="card-h">Fee Breakdown</h3>
88 <div class="fee-breakdown">
89 <div class="fee-row">
90 <span class="muted">Payment processing</span>
91 <span>~2.9% + 30c</span>
92 </div>
93 <div class="fee-row">
94 <span class="muted">Platform fee</span>
95 <span class="fw-bold">$0.00 (0%)</span>
96 </div>
97 </div>
98 <p class="mt-3 mb-0 text-sm muted">
99 We take 0%. ~3% payment processing is the only cost.
100 </p>
101 </div>
102
103 <div class="card-muted">
104 <h3 class="card-h">Sales Tax</h3>
105 <form hx-put="/api/users/me/stripe-tax" hx-swap="none" data-success-toast="Sales tax preference saved">
106 <label class="checkbox-row">
107 <input type="checkbox" name="stripe_tax_enabled" class="check-inline"
108 {% if user.stripe_tax_enabled %}checked{% endif %}
109 data-change="submitOwnForm">
110 <span>Enable Stripe Tax on my checkouts</span>
111 </label>
112 </form>
113 <p class="mt-3 mb-0 text-sm muted">
114 When enabled, Stripe automatically calculates and collects applicable taxes
115 (VAT, sales tax) based on the buyer's location at checkout.
116 You are responsible for configuring your tax registrations in your
117 <a href="https://dashboard.stripe.com/settings/tax" target="_blank" rel="noopener" class="unstyled-link">Stripe Tax settings</a>.
118 </p>
119 </div>
120 </details>
121
122 <p class="text-sm dimmer mb-5">
123 Makenotwork uses Stripe Connect for secure payment processing. We never store your banking information.
124 </p>
125 {% else %}
126 <!-- Not Connected to Stripe -->
127 <div class="stripe-connect-prompt card-muted mb-5">
128 <div class="mb-4">
129 <svg width="80" height="33" viewBox="0 0 60 25" fill="none" xmlns="http://www.w3.org/2000/svg" class="stripe-logo">
130 <path fill-rule="evenodd" clip-rule="evenodd" d="M59.64 14.28C59.64 9.94 57.58 6.52 53.52 6.52C49.44 6.52 47.04 9.94 47.04 14.24C47.04 19.38 49.88 22.04 54.04 22.04C56.08 22.04 57.6 21.56 58.76 20.92V17.74C57.6 18.32 56.24 18.68 54.52 18.68C52.84 18.68 51.36 18.1 51.18 16.06H59.6C59.6 15.82 59.64 14.8 59.64 14.28ZM51.12 13.16C51.12 11.22 52.24 10.38 53.5 10.38C54.72 10.38 55.78 11.22 55.78 13.16H51.12ZM40.68 6.52C38.98 6.52 37.92 7.34 37.32 7.9L37.12 6.78H33.38V24.5L37.54 23.62L37.56 17.8C38.18 18.24 39.08 18.86 40.66 18.86C43.86 18.86 46.78 16.3 46.78 12.52C46.76 9.08 43.82 6.52 40.68 6.52ZM39.7 15.42C38.62 15.42 37.98 15.06 37.56 14.62L37.54 10.58C38 10.1 38.66 9.76 39.7 9.76C41.34 9.76 42.48 11.52 42.48 12.58C42.48 13.68 41.36 15.42 39.7 15.42ZM28.3 5.58L32.48 4.68V1.42L28.3 2.3V5.58ZM28.3 6.78H32.48V18.58H28.3V6.78ZM23.94 7.96L23.68 6.78H20.02V18.58H24.18V11.08C25.1 9.92 26.66 10.14 27.14 10.3V6.78C26.64 6.6 24.86 6.26 23.94 7.96ZM15.68 2.82L11.62 3.68L11.6 15.1C11.6 17.12 13.14 18.86 15.16 18.86C16.28 18.86 17.08 18.66 17.52 18.42V15.16C17.1 15.34 15.66 15.76 15.66 13.74V10.06H17.52V6.78H15.66L15.68 2.82ZM7.36 10.64C7.36 10 7.9 9.74 8.76 9.74C10 9.74 11.54 10.12 12.78 10.82V6.98C11.42 6.42 10.08 6.18 8.76 6.18C5.44 6.18 3.2 7.98 3.2 10.88C3.2 15.4 9.38 14.64 9.38 16.56C9.38 17.32 8.7 17.58 7.78 17.58C6.42 17.58 4.72 17.02 3.34 16.22V20.12C4.88 20.78 6.44 21.06 7.78 21.06C11.18 21.06 13.56 19.32 13.56 16.38C13.54 11.5 7.36 12.42 7.36 10.64Z" fill="#635BFF"/>
131 </svg>
132 </div>
133 <p class="mb-4 muted">
134 Connect your Stripe account to start receiving payments from your sales.
135 </p>
136 <ul class="benefit-list">
137 <li>Direct deposits to your bank</li>
138 <li>Automatic 1099 tax forms</li>
139 <li>Real-time sales dashboard</li>
140 </ul>
141 <a href="/stripe/connect">
142 <button class="btn-primary stripe-connect-btn">
143 Connect with Stripe
144 </button>
145 </a>
146 </div>
147 {% endif %}
148 {% endif %}
149
150 <div class="section-group-label">History</div>
151
152 {% if can_create_projects %}
153 {% if splits_incoming_count > 0 || splits_outgoing_total != "$0.00" %}
154 <details class="form-section" open>
155 <summary><h2 class="subsection-title">Collaborator Payouts</h2></summary>
156 <div class="export-row">
157 <button class="btn-secondary text-sm"
158 data-action="exportCsvButton" data-arg="/api/export/splits" data-arg2="collaborator-payouts.csv">Export CSV</button>
159 </div>
160 <div class="splits-grid">
161 {% if splits_incoming_count > 0 %}
162 <div class="card-muted">
163 <div class="text-xs dimmed">Owed to you (as collaborator)</div>
164 <div class="amount-big">{{ splits_incoming_total }}</div>
165 <div class="text-sm muted">from {{ splits_incoming_count }} sales</div>
166 </div>
167 {% endif %}
168 {% if splits_outgoing_total != "$0.00" %}
169 <div class="card-muted">
170 <div class="text-xs dimmed">You owe collaborators</div>
171 <div class="amount-big">{{ splits_outgoing_total }}</div>
172 </div>
173 {% endif %}
174 </div>
175 <p class="text-sm dimmed">
176 Collaborator payouts are recorded automatically when sales complete on projects with collaborators.
177 Payouts to collaborators are currently settled between project members directly.
178 We plan to automate this process in a future update.
179 </p>
180 </details>
181 {% endif %}
182
183 {% if tips_count > 0 %}
184 <details class="form-section" open>
185 <summary><h2 class="subsection-title">Tips Received ({{ tips_count }})</h2></summary>
186 <div class="card-muted mb-5">
187 <div class="amount-big mb-2">{{ tips_total }} total</div>
188 <div class="text-sm muted">{{ tips_count }} tips received</div>
189 </div>
190 <table class="data-table">
191 <thead>
192 <tr>
193 <th>Date</th>
194 <th>From</th>
195 <th>Amount</th>
196 <th>Message</th>
197 </tr>
198 </thead>
199 <tbody>
200 {% for tip in tips_received %}
201 <tr>
202 <td>{{ tip.date }}</td>
203 <td>{{ tip.tipper_name }}</td>
204 <td>{{ tip.amount }}</td>
205 <td class="tip-message">{% if let Some(msg) = tip.message %}{{ msg }}{% else %}<span class="dimmer">-</span>{% endif %}</td>
206 </tr>
207 {% endfor %}
208 </tbody>
209 </table>
210 </details>
211 {% endif %}
212 {% endif %}
213
214 <div class="transactions-header">
215 <h2 class="m-0 transactions-title">Transactions</h2>
216 <button class="btn-secondary text-sm"
217 hx-post="/api/export/sales"
218 hx-swap="none"
219 data-action="exportCsvButton" data-arg="/api/export/sales" data-arg2="sales.csv">Export CSV</button>
220 </div>
221
222 <div class="filter-controls">
223 <div class="filter-group">
224 <select name="type"
225 hx-get="/dashboard/transactions"
226 hx-target="#transactions-tbody"
227 hx-include="[name='period']">
228 <option value="">All Transactions</option>
229 {% if can_create_projects %}
230 <option value="incoming">Sales</option>
231 <option value="outgoing">Payouts</option>
232 <option value="refund">Refunds</option>
233 {% endif %}
234 <option value="purchases">Purchases</option>
235 </select>
236 </div>
237 <div class="filter-group">
238 <select name="period"
239 hx-get="/dashboard/transactions"
240 hx-target="#transactions-tbody"
241 hx-include="[name='type']">
242 <option value="">All Time</option>
243 <option value="month">This Month</option>
244 <option value="3months">Last 3 Months</option>
245 <option value="year">Last Year</option>
246 </select>
247 </div>
248 </div>
249
250 <table class="data-table">
251 <thead>
252 <tr>
253 <th>Date</th>
254 <th>Type</th>
255 <th>Description</th>
256 <th>Amount</th>
257 <th>Status</th>
258 <th>Details</th>
259 </tr>
260 </thead>
261 <tbody id="transactions-tbody">
262 {% for tx in transactions %}
263 <tr>
264 <td>{{ tx.date }}</td>
265 <td>{{ tx.tx_type }}</td>
266 <td>{{ tx.description }}</td>
267 <td class="{% if tx.is_incoming %}amount-in{% else %}amount-out{% endif %}">{{ tx.amount }}</td>
268 <td><span class="badge {{ tx.status|lowercase }}">{{ tx.status }}</span></td>
269 <td>{{ tx.details }}</td>
270 </tr>
271 {% endfor %}
272 {% if transactions.is_empty() %}
273 <tr>
274 <td colspan="6" class="text-center dimmed">No transactions found</td>
275 </tr>
276 {% endif %}
277 </tbody>
278 </table>
279
280 {% if can_create_projects %}
281 <div hx-get="/dashboard/tabs/contacts" hx-trigger="revealed" hx-swap="innerHTML" id="contacts-section"></div>
282 {% endif %}
283