0036b55618
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 11s
CI / integration (pull_request) Successful in 24s
CI / ui (pull_request) Has been skipped
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m53s
The /_gm console gains a Catalog editor — the source of truth for products. Create / edit / archive-unarchive products, their atom composition and per-rail prices (RUB via direct / VOTE via vk / XTR via telegram / CHIP value), and hard-delete only a never-transacted product (an order or ledger reference forces archive-only, backed by the FK RESTRICT). The archived flag reuses the existing product.active. Activation revalidates the sellable shape — a pack (the chips atom ⇒ a money price per rail, chips-only) or a value (no chips ⇒ a CHIP price); a tournament-bearing product is composable but never sellable yet. Backed by payments AdminCatalog / CreateProduct / UpdateProduct / SetProductActive / DeleteProduct + a pure validateProduct. Tests: validateProduct (pack / value / tournament / duplicate / shape); the console editor end to end (create, edit, archive, delete-if-clean, refuse a transacted delete).
26 lines
1.7 KiB
Go Template
26 lines
1.7 KiB
Go Template
{{define "content" -}}
|
|
{{with .Data}}
|
|
<p class="note"><a href="/_gm/catalog">← all products</a></p>
|
|
<h1>{{.Title}} {{if .Active}}<span class="ok">active</span>{{else}}<span class="warn">archived</span>{{end}}{{if .Transacted}} <span class="pill">transacted</span>{{end}}</h1>
|
|
<section class="panel"><h2>Edit</h2>
|
|
<p class="note">A zero quantity / blank price removes that atom / price. Amounts are in minor units. Saving revalidates the sellable shape when the product is active. Archive / unarchive from the <a href="/_gm/catalog">catalog list</a>.</p>
|
|
<form class="form col" method="post" action="/_gm/catalog/{{.ID}}">
|
|
<label>Title <input type="text" name="title" value="{{.Title}}" maxlength="120" required></label>
|
|
<fieldset><legend>Atoms (quantity; 0 = none)</legend>
|
|
<label>Chips <input type="number" name="chips" min="0" value="{{.Chips}}"></label>
|
|
<label>Hints <input type="number" name="hints" min="0" value="{{.Hints}}"></label>
|
|
<label>No-ads days <input type="number" name="noads" min="0" value="{{.NoAds}}"></label>
|
|
<label>Tournament <input type="number" name="tournament" min="0" value="{{.Tournament}}"></label>
|
|
</fieldset>
|
|
<fieldset><legend>Prices (minor units; 0 = none)</legend>
|
|
<label>RUB — direct (kopecks) <input type="number" name="price_rub" min="0" value="{{.PriceRUB}}"></label>
|
|
<label>VOTE — vk <input type="number" name="price_vote" min="0" value="{{.PriceVote}}"></label>
|
|
<label>XTR — telegram <input type="number" name="price_star" min="0" value="{{.PriceStar}}"></label>
|
|
<label>CHIP — value <input type="number" name="price_chip" min="0" value="{{.PriceChip}}"></label>
|
|
</fieldset>
|
|
<div><button type="submit">Save</button></div>
|
|
</form>
|
|
</section>
|
|
{{end}}
|
|
{{- end}}
|