OOKNET                             [ /  search the index  ]  
──────────────────────────────────────────────────────────────────────────────────────
══════════════════════════════════════════════════════════════════════════════════════
OOKNET   [ /  search  ]  
────────────────────────────────────────────────
════════════════════════════════════════════════
 
 
master @ 176 LINES
 
[ HISTORY ]  [ UP ]
 

---
// Three-card profile header: Identity / Character ranks / Account ranks.
// Cards 2 and 3 share the same `RanksCard` component so the per-character
// and per-account stats stay visually aligned and styled from one place.
import { getClassTextClass } from "../../../lib/wow-constants";
import AccountAlts from "../../AccountAlts/AccountAlts.astro";
import RanksCard from "../RanksCard/RanksCard.astro";
import type { AccountCharSummary, AccountSeasonData } from "../../../lib/types";
import "./PlayerHeader.scss";

interface SeasonData {
  main_spec_id?: number;
  dungeons_completed: number;
  total_runs: number;
  combined_best_time?: number;
  global_ranking?: number;
  regional_ranking?: number;
  realm_ranking?: number;
  global_ranking_bracket?: string;
  regional_ranking_bracket?: string;
  realm_ranking_bracket?: string;
  last_updated?: number;
}

interface Player {
  id: number;
  name: string;
  region: string;
  realm_name: string;
  realm_slug: string;
  class_name?: string;
  active_spec_name?: string;
  race_name?: string;
  avatar_url?: string;
  guild_name?: string;
  average_item_level?: number;
  equipped_item_level?: number;
  all_time_total_runs?: number;
  account_lifetime_total_runs?: number;
  alts?: AccountCharSummary[];
}

interface Props {
  player: Player;
  seasonData: SeasonData;
  seasonId?: string | null;
  accountSeasonData?: AccountSeasonData;
}

const { player, seasonData, seasonId, accountSeasonData } = Astro.props;
const seasonLabel =
  seasonId === "all-time" ? "All Time" : seasonId ? `Season ${seasonId}` : "";

const regionLabel = (player.region || "").toUpperCase();

function getRaceId(raceName: string): number {
  const raceIds: Record<string, number> = {
    Human: 1,
    Orc: 2,
    Dwarf: 3,
    "Night Elf": 4,
    Undead: 5,
    Tauren: 6,
    Gnome: 7,
    Troll: 8,
    Goblin: 9,
    "Blood Elf": 10,
    Draenei: 11,
    Worgen: 22,
  };
  return raceIds[raceName] || 1;
}

const raceId = getRaceId(player.race_name || "Human");
const genderId = 0;
const fallbackUrl = `/wow/static/images/2d/avatar/${raceId}-${genderId}.jpg`;
const avatarUrl = player.avatar_url
  ? `${player.avatar_url}?alt=${fallbackUrl}`
  : fallbackUrl;

const characterSubtitle = [
  player.race_name,
  player.active_spec_name,
  player.class_name,
]
  .filter(Boolean)
  .join(" ");

const accountSubtitle = accountSeasonData
  ? `${accountSeasonData.character_count} character${accountSeasonData.character_c
ount === 1 ? "" : "s"}`
  : undefined;
---

<div class="player-header-cards">
  <section class="player-card player-card--identity">
    <div class="player-identity">
      <img
        src={avatarUrl}
        alt={`${player.name} avatar`}
        class="player-identity__avatar"
      />
      <div class="player-identity__body">
        <div class="player-identity__name-row">
          <h1
            class:list={[
              "player-identity__name",
              getClassTextClass(player.class_name || "common"),
            ]}
          >
            {player.name}
          </h1>
          {
            player.alts && player.alts.length > 0 && (
              <AccountAlts alts={player.alts} align="left" />
            )
          }
        </div>
        {
          player.guild_name && (
            <div class="player-identity__guild">
              &lt;{player.guild_name}&gt;
            </div>
          )
        }
        <div class="player-identity__details">{characterSubtitle}</div>
        <div class="player-identity__ilvl">
          ilvl {player.equipped_item_level || "-"} equipped / {
            player.average_item_level || "-"
          } avg
        </div>
      </div>
    </div>
  </section>

  <RanksCard
    title="Character"
    subtitle={seasonLabel}
    combinedTime={seasonData.combined_best_time}
    combinedTimeBracket={seasonData.global_ranking_bracket}
    globalRanking={seasonData.global_ranking}
    globalBracket={seasonData.global_ranking_bracket}
    regionalRanking={seasonData.regional_ranking}
    regionalBracket={seasonData.regional_ranking_bracket}
    regionLabel={regionLabel}
    realmRanking={seasonData.realm_ranking}
    realmBracket={seasonData.realm_ranking_bracket}
    totalRuns={seasonData.total_runs}
  />

  {
    accountSeasonData ? (
      <RanksCard
        title="Account"
        subtitle={[seasonLabel, accountSubtitle].filter(Boolean).join(" ? ")}
        combinedTime={accountSeasonData.combined_best_time}
        combinedTimeBracket={accountSeasonData.global_ranking_bracket}
        globalRanking={accountSeasonData.global_ranking}
        globalBracket={accountSeasonData.global_ranking_bracket}
        regionalRanking={accountSeasonData.regional_ranking}
        regionalBracket={accountSeasonData.regional_ranking_bracket}
        regionLabel={regionLabel}
        realmRanking={accountSeasonData.realm_ranking}
        realmBracket={accountSeasonData.realm_ranking_bracket}
        totalRuns={accountSeasonData.total_runs}
      />
    ) : (
      <section class="player-card player-card--account-empty">
        <div class="player-card__placeholder">
          <h2 class="player-card__placeholder-title">Account</h2>
          <p>This character isn't grouped to an account yet.</p>
        </div>
      </section>
    )
  }
</div>

---
// Three-card profile header: Identity / Cha
racter ranks / Account ranks.
// Cards 2 and 3 share the same `RanksCard` 
component so the per-character
// and per-account stats stay visually align
ed and styled from one place.
import { getClassTextClass } from "../../../
lib/wow-constants";
import AccountAlts from "../../AccountAlts/A
ccountAlts.astro";
import RanksCard from "../RanksCard/RanksCar
d.astro";
import type { AccountCharSummary, AccountSea
sonData } from "../../../lib/types";
import "./PlayerHeader.scss";

interface SeasonData {
  main_spec_id?: number;
  dungeons_completed: number;
  total_runs: number;
  combined_best_time?: number;
  global_ranking?: number;
  regional_ranking?: number;
  realm_ranking?: number;
  global_ranking_bracket?: string;
  regional_ranking_bracket?: string;
  realm_ranking_bracket?: string;
  last_updated?: number;
}

interface Player {
  id: number;
  name: string;
  region: string;
  realm_name: string;
  realm_slug: string;
  class_name?: string;
  active_spec_name?: string;
  race_name?: string;
  avatar_url?: string;
  guild_name?: string;
  average_item_level?: number;
  equipped_item_level?: number;
  all_time_total_runs?: number;
  account_lifetime_total_runs?: number;
  alts?: AccountCharSummary[];
}

interface Props {
  player: Player;
  seasonData: SeasonData;
  seasonId?: string | null;
  accountSeasonData?: AccountSeasonData;
}

const { player, seasonData, seasonId, accoun
tSeasonData } = Astro.props;
const seasonLabel =
  seasonId === "all-time" ? "All Time" : sea
sonId ? `Season ${seasonId}` : "";

const regionLabel = (player.region || "").to
UpperCase();

function getRaceId(raceName: string): number
 {
  const raceIds: Record<string, number> = {
    Human: 1,
    Orc: 2,
    Dwarf: 3,
    "Night Elf": 4,
    Undead: 5,
    Tauren: 6,
    Gnome: 7,
    Troll: 8,
    Goblin: 9,
    "Blood Elf": 10,
    Draenei: 11,
    Worgen: 22,
  };
  return raceIds[raceName] || 1;
}

const raceId = getRaceId(player.race_name ||
 "Human");
const genderId = 0;
const fallbackUrl = `/wow/static/images/2d/a
vatar/${raceId}-${genderId}.jpg`;
const avatarUrl = player.avatar_url
  ? `${player.avatar_url}?alt=${fallbackUrl}
`
  : fallbackUrl;

const characterSubtitle = [
  player.race_name,
  player.active_spec_name,
  player.class_name,
]
  .filter(Boolean)
  .join(" ");

const accountSubtitle = accountSeasonData
  ? `${accountSeasonData.character_count} ch
aracter${accountSeasonData.character_count =
== 1 ? "" : "s"}`
  : undefined;
---

<div class="player-header-cards">
  <section class="player-card player-card--i
dentity">
    <div class="player-identity">
      <img
        src={avatarUrl}
        alt={`${player.name} avatar`}
        class="player-identity__avatar"
      />
      <div class="player-identity__body">
        <div class="player-identity__name-ro
w">
          <h1
            class:list={[
              "player-identity__name",
              getClassTextClass(player.class
_name || "common"),
            ]}
          >
            {player.name}
          </h1>
          {
            player.alts && player.alts.lengt
h > 0 && (
              <AccountAlts alts={player.alts
} align="left" />
            )
          }
        </div>
        {
          player.guild_name && (
            <div class="player-identity__gui
ld">
              &lt;{player.guild_name}&gt;
            </div>
          )
        }
        <div class="player-identity__details
">{characterSubtitle}</div>
        <div class="player-identity__ilvl">
          ilvl {player.equipped_item_level |
| "-"} equipped / {
            player.average_item_level || "-"
          } avg
        </div>
      </div>
    </div>
  </section>

  <RanksCard
    title="Character"
    subtitle={seasonLabel}
    combinedTime={seasonData.combined_best_t
ime}
    combinedTimeBracket={seasonData.global_r
anking_bracket}
    globalRanking={seasonData.global_ranking
}
    globalBracket={seasonData.global_ranking
_bracket}
    regionalRanking={seasonData.regional_ran
king}
    regionalBracket={seasonData.regional_ran
king_bracket}
    regionLabel={regionLabel}
    realmRanking={seasonData.realm_ranking}
    realmBracket={seasonData.realm_ranking_b
racket}
    totalRuns={seasonData.total_runs}
  />

  {
    accountSeasonData ? (
      <RanksCard
        title="Account"
        subtitle={[seasonLabel, accountSubti
tle].filter(Boolean).join(" ? ")}
        combinedTime={accountSeasonData.comb
ined_best_time}
        combinedTimeBracket={accountSeasonDa
ta.global_ranking_bracket}
        globalRanking={accountSeasonData.glo
bal_ranking}
        globalBracket={accountSeasonData.glo
bal_ranking_bracket}
        regionalRanking={accountSeasonData.r
egional_ranking}
        regionalBracket={accountSeasonData.r
egional_ranking_bracket}
        regionLabel={regionLabel}
        realmRanking={accountSeasonData.real
m_ranking}
        realmBracket={accountSeasonData.real
m_ranking_bracket}
        totalRuns={accountSeasonData.total_r
uns}
      />
    ) : (
      <section class="player-card player-car
d--account-empty">
        <div class="player-card__placeholder
">
          <h2 class="player-card__placeholde
r-title">Account</h2>
          <p>This character isn't grouped to
 an account yet.</p>
        </div>
      </section>
    )
  }
</div>
 
──────────────────────────────────────────────────────────────────────────────────────
OOKNET
────────────────────────────────────────────────
OOKNET