Skip to main content

Overview

The MilestoneCard component displays information about a character milestone, including its level, reward, and requirements. It provides an unlock button that emits an event when clicked.

Component metadata

  • Selector: app-milestone-card
  • Source: /src/app/pages/milestones/components/milestone-card/milestone-card.ts
  • Standalone: Yes (uses imports array)

Template structure

The card displays milestone information in a vertical layout:
<div class="flex items-center flex-col">
  <p class="text-xl font-bold">Level {{ milestone().level }}</p>
  <p>
    Reward: <span class="font-bold"> +{{ milestone().reward }} {{ milestone().type }} </span>
  </p>
  <div class="flex flex-col items-center mt-3">
    <p>Requirement:</p>
    <p>{{ milestone().requirement }}</p>
  </div>
  <button
    class="bg-blue-300 text-blue-950 font-bold text-xl py-4 px-8 rounded-lg mt-5"
    (click)="onUnlockClick()"
  >
    Unlock Level
  </button>
</div>

Inputs

milestone
Milestone
required
The milestone object to display. Must include level, reward, type, and requirement properties.

Milestone interface

interface Milestone {
  id: string;
  type: 'Strength' | 'Intelligence' | 'Endurance';
  requirement: string;
  reward: number;
  achieved: boolean;
  achievedAt?: Date;
  level: number;
}

Outputs

unlockMilestone
EventEmitter<Milestone>
Emitted when the unlock button is clicked, passing the milestone object.

Methods

onUnlockClick()

Internal method that emits the unlockMilestone output event with the current milestone.
onUnlockClick() {
  this.unlockMilestone.emit(this.milestone());
}

Usage

import { MilestoneCard } from './components/milestone-card/milestone-card';
import { Milestone } from './models/milestone.model';

@Component({
  selector: 'app-milestones-page',
  imports: [MilestoneCard],
  template: `
    @for (milestone of milestones; track milestone.id) {
      <app-milestone-card
        [milestone]="milestone"
        (unlockMilestone)="handleUnlock($event)"
      />
    }
  `
})
export class MilestonesPage {
  milestones: Milestone[] = [];

  handleUnlock(milestone: Milestone) {
    console.log('Unlocking milestone:', milestone.id);
    // Handle unlock logic
  }
}

Example

const milestone: Milestone = {
  id: 'str-1',
  type: 'Strength',
  requirement: 'Defeat 10 enemies',
  reward: 5,
  achieved: false,
  level: 1
};
When rendered, this displays:
  • Level 1 as the heading
  • Reward: +5 Strength showing the stat bonus
  • Requirement: Defeat 10 enemies explaining what’s needed
  • An “Unlock Level” button that emits the milestone when clicked
The component uses Angular’s signal-based inputs with input.required(), ensuring type safety and requiring the milestone property to be provided.

Build docs developers (and LLMs) love