Menu

Change language

GitHub repo

Use Cases Role Cards

blockmarketing

Grid of role cards, each stating the job to be done, the first week of work, and the metric that role is measured on, so a reader can self-select without a tab interaction.

Installation

$npx uipkge-ng@latest add use-cases-role-cards
Manifest:https://uipkge.dev/r/angular/use-cases-role-cards.jsonInstalls to:src/app/components/blocks/use-cases-role-cards/

Variants

Loading interactive previews…

Schema

Type aliases exported from this item's source. Use these to shape the data you pass in.

RoleCard
interface RoleCard {
  initials: string
  role: string
  job: string
  week: string
  metric: string
}

Files installed (2)

  • src/app/components/blocks/use-cases-role-cards/use-cases-role-cards.component.ts4.8 kB
    // Grid of role cards, each stating the job to be done, the first week of work,
    // and the metric that role is measured on, so a reader can self-select without
    // a tab interaction. Port of the React block 1:1 (static, no client state).
    import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
    import { ArrowUpRight, LucideAngularModule } from 'lucide-angular'
    import { cn } from '@/lib/utils'
    import { UiAvatarComponent, UiAvatarFallbackComponent } from '@/ui/avatar/avatar.component'
    import { UiBadgeComponent } from '@/ui/badge/badge.component'
    import { UiButtonComponent } from '@/ui/button/button.component'
    import { UiCardComponent, UiCardContentComponent } from '@/ui/card/card.component'
    import { UiSeparatorComponent } from '@/ui/separator/separator.component'
    
    interface RoleCard {
      initials: string
      role: string
      job: string
      week: string
      metric: string
    }
    
    const roles: RoleCard[] = [
      {
        initials: 'FC',
        role: 'Financial controller',
        job: 'Close the books without a reconciliation relay.',
        week: 'Reconcile revenue and margin against the ledger, then lock the period.',
        metric: 'Days to close',
      },
      {
        initials: 'AL',
        role: 'Analytics lead',
        job: 'Stop being a query queue for the rest of the company.',
        week: 'Publish the ten numbers that generate the most tickets as certified metrics.',
        metric: 'Ad-hoc requests per month',
      },
      {
        initials: 'RO',
        role: 'RevOps',
        job: 'Make forecast review about the forecast.',
        week: 'Agree one pipeline definition with finance and snapshot it weekly.',
        metric: 'Forecast accuracy band',
      },
      {
        initials: 'DE',
        role: 'Data engineer',
        job: 'Stop owning an undocumented reporting service.',
        week: 'Move definitions into the repo and delete the bespoke extract jobs.',
        metric: 'Pipelines maintained',
      },
    ]
    
    @Component({
      changeDetection: ChangeDetectionStrategy.Eager,
      selector: 'ui-use-cases-role-cards, [ui-use-cases-role-cards]',
      standalone: true,
      // React renders the root <section> itself: the host stays out of layout and `class` goes to the root.
      host: { '[attr.class]': '"contents"' },
      imports: [
        LucideAngularModule,
        UiAvatarComponent,
        UiAvatarFallbackComponent,
        UiBadgeComponent,
        UiButtonComponent,
        UiCardComponent,
        UiCardContentComponent,
        UiSeparatorComponent,
      ],
      template: `
        <section data-slot="use-cases-role-cards" [class]="rootClass">
          <div class="mx-auto max-w-6xl px-6 py-20 lg:py-28">
            <div class="max-w-2xl">
              <span ui-badge variant="secondary">By role</span>
              <h2 class="mt-4 text-3xl font-semibold tracking-tight sm:text-4xl">Find the card with your job on it</h2>
              <p class="text-muted-foreground mt-3 text-lg">
                Each one names the work of the first week and the number that role is actually judged on.
              </p>
            </div>
    
            <div class="mt-10 grid gap-4 sm:grid-cols-2">
              @for (role of roles; track role.role) {
                <div ui-card class="group">
                  <div ui-card-content class="flex h-full flex-col p-6">
                    <div class="flex items-center gap-3">
                      <ui-avatar class="size-9">
                        <ui-avatar-fallback class="text-xs">{{ role.initials }}</ui-avatar-fallback>
                      </ui-avatar>
                      <p class="text-sm font-semibold">{{ role.role }}</p>
                    </div>
    
                    <p class="mt-4 text-base leading-snug font-medium text-balance">{{ role.job }}</p>
    
                    <ui-separator class="my-4" />
    
                    <p class="text-muted-foreground font-mono text-xs tracking-[0.14em] uppercase">First week</p>
                    <p class="text-muted-foreground mt-2 text-sm leading-relaxed">{{ role.week }}</p>
    
                    <div class="border-border mt-auto flex items-center justify-between gap-3 border-t pt-4">
                      <span class="text-xs">
                        <span class="text-muted-foreground">Measured on </span>
                        <span class="font-medium">{{ role.metric }}</span>
                      </span>
                      <button ui-button variant="ghost" size="sm" class="h-auto shrink-0 px-2 py-1">
                        Read
                        <lucide-icon
                          [img]="ArrowUpRight"
                          class="ml-1 size-3.5 transition-transform group-hover:translate-x-0.5 group-hover:-translate-y-0.5"
                        />
                      </button>
                    </div>
                  </div>
                </div>
              }
            </div>
          </div>
        </section>
      `,
    })
    export class UiUseCasesRoleCardsComponent {
      protected readonly ArrowUpRight = ArrowUpRight
      protected readonly roles = roles
    
      @Input('class') className?: string
    
      get rootClass(): string {
        return cn('bg-background', this.className)
      }
    }
    
  • src/app/components/blocks/use-cases-role-cards/index.ts0.1 kB

Raw manifest:https://uipkge.dev/r/angular/use-cases-role-cards.json