docs
This commit is contained in:
265
apps/web/src/app/features/npc/merchant-page.component.html
Normal file
265
apps/web/src/app/features/npc/merchant-page.component.html
Normal file
@@ -0,0 +1,265 @@
|
||||
@if (store.loading()) {
|
||||
<p class="merchant__status">Approaching…</p>
|
||||
} @else if (store.error()) {
|
||||
<div class="merchant__status merchant__status--error" role="alert">
|
||||
<p>{{ store.error() }}</p>
|
||||
<button type="button" class="merchant__button" (click)="leave()">
|
||||
Back to the gate
|
||||
</button>
|
||||
</div>
|
||||
} @else if (store.interaction(); as interaction) {
|
||||
<article class="merchant">
|
||||
<header class="merchant__identity">
|
||||
<img
|
||||
class="merchant__portrait"
|
||||
[src]="interaction.npc.portraitPath"
|
||||
[alt]="interaction.npc.name"
|
||||
(error)="($any($event.target).style.visibility = 'hidden')"
|
||||
/>
|
||||
<div class="merchant__naming">
|
||||
<h1 class="merchant__name">{{ interaction.npc.name }}</h1>
|
||||
@if (interaction.npc.title) {
|
||||
<p class="merchant__title">{{ interaction.npc.title }}</p>
|
||||
}
|
||||
@if (interaction.npc.description) {
|
||||
<p class="merchant__description">{{ interaction.npc.description }}</p>
|
||||
}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@if (interaction.dialogue) {
|
||||
<blockquote class="merchant__dialogue" data-dialogue>
|
||||
{{ interaction.dialogue.text }}
|
||||
</blockquote>
|
||||
}
|
||||
|
||||
<nav class="merchant__actions" aria-label="Interactions">
|
||||
@for (action of interaction.availableActions; track action.type) {
|
||||
<button
|
||||
type="button"
|
||||
class="merchant__button"
|
||||
[class.merchant__button--active]="
|
||||
(action.type === 'OPEN_EXCHANGE' && isPanel('EXCHANGE')) ||
|
||||
(action.type === 'OPEN_SHOP' && isPanel('SHOP')) ||
|
||||
(action.type === 'TALK' && isPanel('DIALOGUE'))
|
||||
"
|
||||
[attr.data-action]="action.type"
|
||||
(click)="activate(action.type, action.key)"
|
||||
>
|
||||
{{ action.label }}
|
||||
</button>
|
||||
}
|
||||
<button type="button" class="merchant__button" (click)="leave()">
|
||||
Leave
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
@if (store.actionError()) {
|
||||
<p class="merchant__error" role="alert">{{ store.actionError() }}</p>
|
||||
}
|
||||
|
||||
@if (isPanel('EXCHANGE') && store.exchange(); as exchange) {
|
||||
<section class="merchant__panel" aria-label="Trade in goods">
|
||||
<h2 class="merchant__panel-title">{{ exchange.profileName }}</h2>
|
||||
|
||||
<app-loot-capacity-strip [capacities]="exchange.capacities" />
|
||||
|
||||
@if (exchange.offers.length === 0) {
|
||||
<p class="merchant__empty">There is nothing here he will take.</p>
|
||||
} @else {
|
||||
<ul class="trade-list">
|
||||
@for (offer of exchange.offers; track offer.itemKey) {
|
||||
<li
|
||||
class="trade-row"
|
||||
[class.trade-row--empty]="offer.quantityCarried === 0"
|
||||
[attr.data-trade-item]="offer.itemKey"
|
||||
>
|
||||
<img
|
||||
class="trade-row__icon"
|
||||
[src]="offer.iconPath"
|
||||
[alt]=""
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<div class="trade-row__naming">
|
||||
<span class="trade-row__name">{{ offer.itemName }}</span>
|
||||
<span class="trade-row__carried" data-carried>
|
||||
Carrying {{ offer.quantityCarried }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="trade-row__value" data-value>
|
||||
<span class="trade-row__silver"
|
||||
>{{ offer.silverPerStep }} Silver</span
|
||||
>
|
||||
<span class="trade-row__rep"
|
||||
>+{{ offer.reputationPerStep }}
|
||||
{{ offer.factionName }}</span
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="trade-row__picker">
|
||||
<button
|
||||
type="button"
|
||||
class="trade-row__step"
|
||||
aria-label="Trade fewer"
|
||||
[disabled]="
|
||||
offer.quantityCarried === 0 || store.pending() !== null
|
||||
"
|
||||
(click)="step(offer.itemKey, -1, offer.inputQuantity)"
|
||||
>
|
||||
−
|
||||
</button>
|
||||
<input
|
||||
class="trade-row__quantity"
|
||||
type="number"
|
||||
min="0"
|
||||
[max]="offer.quantityCarried"
|
||||
[step]="offer.inputQuantity"
|
||||
[value]="quantityFor(offer.itemKey)"
|
||||
[disabled]="
|
||||
offer.quantityCarried === 0 || store.pending() !== null
|
||||
"
|
||||
[attr.aria-label]="'Quantity of ' + offer.itemName"
|
||||
(input)="
|
||||
onQuantityInput(offer.itemKey, $any($event.target).value)
|
||||
"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
class="trade-row__step"
|
||||
aria-label="Trade more"
|
||||
[disabled]="
|
||||
offer.quantityCarried === 0 || store.pending() !== null
|
||||
"
|
||||
(click)="step(offer.itemKey, 1, offer.inputQuantity)"
|
||||
>
|
||||
+
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
|
||||
<footer class="trade-footer">
|
||||
<p class="trade-footer__preview" data-preview>
|
||||
Selected:
|
||||
<strong>{{ store.preview().silver }} Silver</strong>
|
||||
and
|
||||
<strong>{{ store.preview().reputation }} Reputation</strong>
|
||||
</p>
|
||||
<div class="trade-footer__buttons">
|
||||
<button
|
||||
type="button"
|
||||
class="merchant__button"
|
||||
[disabled]="store.pending() !== null"
|
||||
(click)="store.selectAll()"
|
||||
>
|
||||
Select All
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="merchant__button merchant__button--primary"
|
||||
data-trade-confirm
|
||||
[disabled]="!store.hasSelection() || store.pending() !== null"
|
||||
(click)="store.tradeSelected()"
|
||||
>
|
||||
{{ store.pending() === 'trade' ? 'Handing over…' : 'Trade Selected' }}
|
||||
</button>
|
||||
</div>
|
||||
</footer>
|
||||
}
|
||||
|
||||
@if (store.lastTrade(); as trade) {
|
||||
<section class="trade-summary" data-trade-summary aria-live="polite">
|
||||
<h3 class="trade-summary__title">Trade Complete</h3>
|
||||
<ul class="trade-summary__consumed">
|
||||
@for (entry of trade.consumed; track entry.itemKey) {
|
||||
<li>{{ entry.quantity }} × {{ entry.itemName }} handed in</li>
|
||||
}
|
||||
</ul>
|
||||
<ul class="trade-summary__rewards">
|
||||
<li>+{{ trade.rewards.silver }} Silver</li>
|
||||
<li>+{{ trade.rewards.regionalReputation }} Border Watch Reputation</li>
|
||||
@if (trade.rewards.worldRenown > 0) {
|
||||
<li class="trade-summary__renown" data-renown>
|
||||
+{{ trade.rewards.worldRenown }} World Renown
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
@if (trade.reputationRankChanged) {
|
||||
<p class="trade-summary__rank" data-rank-changed>
|
||||
The Border Watch now regards you differently.
|
||||
</p>
|
||||
}
|
||||
<button
|
||||
type="button"
|
||||
class="merchant__button"
|
||||
(click)="store.dismissTradeSummary()"
|
||||
>
|
||||
Done
|
||||
</button>
|
||||
</section>
|
||||
}
|
||||
</section>
|
||||
}
|
||||
|
||||
@if (isPanel('SHOP') && store.shop(); as shop) {
|
||||
<section class="merchant__panel" aria-label="Wares for sale">
|
||||
<h2 class="merchant__panel-title">{{ shop.shopName }}</h2>
|
||||
<p class="merchant__purse" data-purse>{{ shop.silver }} Silver</p>
|
||||
|
||||
<ul class="shop-list">
|
||||
@for (offer of shop.offers; track offer.itemKey) {
|
||||
<li class="shop-row" [attr.data-shop-item]="offer.itemKey">
|
||||
<img
|
||||
class="shop-row__icon"
|
||||
[src]="offer.iconPath"
|
||||
[alt]=""
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<div class="shop-row__naming">
|
||||
<span class="shop-row__name">{{ offer.itemName }}</span>
|
||||
<span class="shop-row__description">{{
|
||||
offer.itemDescription
|
||||
}}</span>
|
||||
</div>
|
||||
<span class="shop-row__price">{{ offer.price }} Silver</span>
|
||||
<button
|
||||
type="button"
|
||||
class="merchant__button"
|
||||
[disabled]="
|
||||
!offer.unlocked ||
|
||||
!offer.affordable ||
|
||||
store.pending() !== null
|
||||
"
|
||||
(click)="store.buy(offer.itemKey)"
|
||||
>
|
||||
@if (!offer.unlocked) {
|
||||
Locked
|
||||
} @else if (!offer.affordable) {
|
||||
Too costly
|
||||
} @else {
|
||||
Buy
|
||||
}
|
||||
</button>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
|
||||
@if (store.lastPurchase(); as purchase) {
|
||||
<p class="shop-receipt" data-purchase aria-live="polite">
|
||||
Bought {{ purchase.quantity }} × {{ purchase.itemName }} for
|
||||
{{ purchase.silverSpent }} Silver.
|
||||
<button
|
||||
type="button"
|
||||
class="merchant__link"
|
||||
(click)="store.dismissPurchase()"
|
||||
>
|
||||
Dismiss
|
||||
</button>
|
||||
</p>
|
||||
}
|
||||
</section>
|
||||
}
|
||||
</article>
|
||||
}
|
||||
Reference in New Issue
Block a user