| 1 | {{/* abono/owner-members: GET /admin/members, every holding with its |
| 2 | status and where it came from, "sync with Stripe now", the paying |
| 3 | subscriptions no plan recognises (each with a form that puts it onto |
| 4 | a plan), and the form that gives a free membership (a comp). A comp |
| 5 | still granting has a link to its own confirm page, which ends it. A |
| 6 | subscription held only by abono's 30-day backstop is flagged with the |
| 7 | day access stops. |
| 8 | |
| 9 | Data: |
| 10 | Title string, the page title's message key |
| 11 | On bool, Stripe (or the sandbox) is configured |
| 12 | Members []abonoMember, {Subject, Label, Holding, EndURL}: |
| 13 | Label is what to call the member |
| 14 | Unrecognised []abonoUnrecognised, {SubscriptionID, PriceID, |
| 15 | Subject, Label, ...}; empty while Stripe is off |
| 16 | Now time.Time, the moment holdings are described at |
| 17 | Offers []abono.Offer, the plans a comp can give |
| 18 | PlanOptions []abonoOption, the same as field-select options |
| 19 | AdoptOptions []abonoOption, the plans, none selected, for adopting |
| 20 | Form abonoCompForm, {Member, Plan, Ends, Note, Errors}: the |
| 21 | comp form as posted, Errors a message key by field |
| 22 | SyncAction string, where "sync now" posts |
| 23 | CompAction string, where the comp form posts |
| 24 | AdoptAction string, where an adopt form posts (with from=members) |
| 25 | StripeURL string, the Stripe page |
| 26 | Done *abonoNotice, {Kind, N, Plan}: what the last action did |
| 27 | Error string, a message key, or "" |
| 28 | L the request's localizer */}} |
| 29 | {{define "content"}}{{$L := localizer $}} |
| 30 | {{template "page-header" dict "L" $L "Title" (T $L .Title) "Sub" (T $L "abono.owner.members_intro")}} |
| 31 | {{with .Done}}{{if eq .Kind "sync"}}{{if eq .N 1}}{{template "notice" (T $L "abono.owner.sync_done_one")}}{{else}}{{template "notice" (Tf $L "abono.owner.sync_done" "n" .N)}}{{end}}{{else if eq .Kind "comp"}}{{template "notice" (Tf $L "abono.owner.free_given" "plan" .Plan)}}{{else if eq .Kind "end"}}{{template "notice" (T $L "abono.owner.end_done")}}{{else if eq .Kind "adopt"}}{{template "notice" (Tf $L "abono.owner.adopted" "plan" .Plan)}}{{end}}{{end}} |
| 32 | {{with .Error}}{{template "callout" dict "L" $L "Tone" "negative" "Focus" true "Body" (T $L .)}}{{end}} |
| 33 | {{if .On}}<form rst-form-actions method="post" action="{{.SyncAction}}"><button type="submit" rst-btn>{{T $L "abono.button.sync"}}</button></form> |
| 34 | <p>{{T $L "abono.owner.sync_help"}}</p> |
| 35 | {{else}}<p>{{T $L "abono.owner.nothing_for_sale"}} <a href="{{.StripeURL}}">{{T $L "abono.owner.stripe_title"}}</a></p> |
| 36 | {{end}} |
| 37 | {{if .Members}}<div rst-box> |
| 38 | <table> |
| 39 | <thead><tr><th scope="col">{{T $L "abono.owner.col_member"}}</th><th scope="col">{{T $L "abono.owner.col_plan"}}</th><th scope="col">{{T $L "abono.owner.col_status"}}</th><th scope="col">{{T $L "abono.owner.col_source"}}</th></tr></thead> |
| 40 | <tbody> |
| 41 | {{range .Members}}<tr> |
| 42 | <td>{{.Label}}</td> |
| 43 | <td>{{.Plan}}</td> |
| 44 | <td>{{template "abono-status" dict "L" $L "Holding" .Holding "Now" $.Now}}{{if .Holding.Backstop}}{{$s := .Holding.Describe $.Now}} <small>{{$s.Sentence (T $L "abono.owner.backstop") ""}}</small>{{end}}</td> |
| 45 | <td>{{if eq .Source "comp"}}{{T $L "abono.owner.source_free"}}{{with .EndURL}} <a href="{{.}}">{{T $L "abono.button.end_free"}}</a>{{end}}{{else}}{{T $L "abono.owner.source_paid"}}{{end}}</td> |
| 46 | </tr> |
| 47 | {{end}}</tbody> |
| 48 | </table> |
| 49 | </div> |
| 50 | {{else}}{{template "empty-state" dict "L" $L "Body" (T $L "abono.owner.members_empty")}} |
| 51 | {{end}} |
| 52 | {{if .On}}<section rst-box aria-labelledby="abono-unrecognised-title"> |
| 53 | <h2 id="abono-unrecognised-title">{{T $L "abono.owner.unrecognised_title"}}</h2> |
| 54 | {{if .Unrecognised}}<p>{{T $L "abono.owner.unrecognised_body"}}</p> |
| 55 | <p>{{T $L "abono.owner.unrecognised_warn"}}</p> |
| 56 | {{range .Unrecognised}}<form rst-form method="post" action="{{$.AdoptAction}}" data-abono-unrecognised="{{.SubscriptionID}}"> |
| 57 | <p><code>{{.SubscriptionID}}</code> <code>{{.PriceID}}</code> {{.Label}}</p> |
| 58 | <input type="hidden" name="subscription" value="{{.SubscriptionID}}"> |
| 59 | <input type="hidden" name="from" value="members"> |
| 60 | {{template "field-select" dict "L" $L "ID" (printf "abono-adopt-%s" .SubscriptionID) "Name" "plan" "Label" (T $L "abono.owner.adopt_plan") "Options" $.AdoptOptions "Required" true}} |
| 61 | <button type="submit" rst-btn>{{T $L "abono.button.adopt"}}</button> |
| 62 | </form> |
| 63 | {{end}} |
| 64 | {{else}}<p>{{T $L "abono.owner.unrecognised_none"}}</p> |
| 65 | {{end}} |
| 66 | </section> |
| 67 | {{end}} |
| 68 | {{if .Offers}}{{$memberErr := ""}}{{$planErr := ""}}{{with .Form.Errors}}{{with index . "member"}}{{$memberErr = T $L .}}{{end}}{{with index . "plan"}}{{$planErr = T $L .}}{{end}}{{end}}<section rst-box aria-labelledby="abono-free-title"> |
| 69 | <h2 id="abono-free-title">{{T $L "abono.owner.free_title"}}</h2> |
| 70 | <p>{{T $L "abono.owner.free_help"}}</p> |
| 71 | <form rst-form method="post" action="{{.CompAction}}"> |
| 72 | {{template "field-text" dict "L" $L "Name" "member" "Label" (T $L "abono.owner.free_member") "Type" "email" "Value" .Form.Member "Required" true "Autocomplete" "off" "Error" $memberErr}} |
| 73 | {{template "field-select" dict "L" $L "ID" "plan" "Name" "plan" "Label" (T $L "abono.owner.free_plan") "Options" .PlanOptions "Required" true "Error" $planErr}} |
| 74 | {{template "field-date" dict "L" $L "Name" "ends" "Label" (T $L "abono.owner.free_ends") "Value" .Form.Ends "Hint" (T $L "abono.owner.free_ends_hint") "Plain" true}} |
| 75 | {{template "field-text" dict "L" $L "Name" "note" "Label" (T $L "abono.owner.free_note") "Value" .Form.Note "Hint" (T $L "abono.owner.free_note_hint")}} |
| 76 | {{template "form-foot" dict "L" $L "Submit" (T $L "abono.button.give_free")}} |
| 77 | </form> |
| 78 | </section> |
| 79 | {{end}} |
| 80 | {{end}} |
| 81 | |