ClubItemCardView.razor

Razor panel that renders a club item or reward card. It picks a rarity style (bronze, silver, gold, elite) from reward, training or cosmetic data and draws the name, coin value, cosmetic artwork and club crest. Builds a render hash to limit rebuilds.

Rough Code
@using Sandbox
@using Sandbox.UI
@using Socer
@using System
@inherits Panel

<button class="football-card club-item-card rarity-@Material @(Material is "bronze" or "silver" or "gold" or "elite"?"faceted-card":"") @(Cosmetic?"cosmetic-item":"") @(Kind=="coins"?"coin-item":"") @CssClass" disabled="@Disabled" onclick=@(()=>OnSelected?.Invoke())>
    <div class="card-grain"></div><div class="card-light"></div><div class="card-engraving"></div>
    @if(Kind=="coins"){<div class="card-top item-card-top"><label class="ovr">@TopValue</label><label class="role">@TopLabel</label></div>}
    <div class="portrait item-portrait">
        @if(Kind=="kit")
        {
            <img class="cosmetic-artwork" src="@($"/cosmetics/kit-{Reward.CosmeticId}.svg")" />
        }
        else if(Kind=="ball")
        {
            <img class="cosmetic-artwork" src="@($"/cosmetics/ball-{Reward.CosmeticId}.svg")" />
        }
        else if(Kind=="training")
        {
            <div class="training-art training-upgrade-art"></div>
        }
        else{<div class="item-emblem"><img src="/ui-icons/ui-bold-nav-coins.svg" /></div>}
        <div class="item-spark first"></div><div class="item-spark second"></div>
    </div>
    @if(Cosmetic){<div class="card-data-panel cosmetic-data-panel"><label>@RarityName</label></div>}
    else if(Kind=="training")
    {<div class="card-data-panel cosmetic-data-panel localized-text"><label class="item-name">@(GamePreferences.Russian?"УЛУЧШЕНИЕ":"UPGRADE")</label><label class="item-rarity">@RarityName</label></div>}
    else{
    <div class="card-data-panel">
    <div class="surname item-name @(Name.Length>16?"name-long":"")">@Name</div>
    <div class="card-bottom"><div class="card-stats item-stats">
        <div class="card-stat"><label>COINS</label><b>+@Reward?.Coins</b></div>
    </div><div class="card-insignia"><img class="card-club-mark" src="@ClubIdentity.Crest(0)" /><label class="card-tier">@Kind.ToUpperInvariant()</label></div></div>
    </div>}
</button>

@code {
    [Parameter] public PackReward Reward {get;set;}
    [Parameter] public TrainingCardItem Training {get;set;}
    [Parameter] public string CssClass {get;set;}="";
    [Parameter] public bool Disabled {get;set;}
    [Parameter] public Action OnSelected {get;set;}
    TrainingCardItem Drill=>Training??Reward?.Training;
    string Kind=>Reward?.Kind??"training";
    bool Cosmetic=>Kind is "kit" or "ball";
    string Name=>Reward?.Name??Drill?.Name??"Upgrade card";
    int Grade=>Kind switch {"training"=>Math.Clamp(Drill?.Grade??1,1,3)-1,"kit"=>ClubCosmetics.Kit(Reward?.CosmeticId).PackTier+1,"ball"=>ClubCosmetics.Ball(Reward?.CosmeticId).PackTier+1,_=>0};
    string Material=>Grade switch {0=>"bronze",1=>"silver",2=>"gold",_=>"elite"};
    string RarityName=>GamePreferences.Russian?(Grade switch{0=>"БРОНЗА",1=>"СЕРЕБРО",2=>"ЗОЛОТО",_=>"ЭЛИТА"}):Material.ToUpperInvariant();
    string TopValue=>$"{Reward?.Coins??0}";
    string TopLabel=>"COINS";
    protected override int BuildHash()=>HashCode.Combine(Kind,Drill?.Grade,Reward?.Coins,Reward?.CosmeticId,CssClass,Disabled,Name,GamePreferences.Russian);
}