Menu

Change language

GitHub repo

Ratings — Award Wall

blockmarketing

Grid of third-party awards, each naming the awarding body, the category, and the period it covers, so a badge wall stays checkable rather than decorative.

Installation

$npx uipkge-ng@latest add ratings-award-wall
Manifest:https://uipkge.dev/r/angular/ratings-award-wall.jsonInstalls to:src/app/components/blocks/ratings-award-wall/

Variants

Loading interactive previews…

Schema

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

AwardEntry
interface AwardEntry {
  body: string
  category: string
  period: string
}

Files installed (2)

  • src/app/components/blocks/ratings-award-wall/ratings-award-wall.component.ts3.7 kB
    // Grid of third-party awards, each naming the awarding body, the category, and the
    // period it covers, so a badge wall stays checkable rather than decorative. Port of the
    // React block 1:1.
    import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
    import { Award, LucideAngularModule } from 'lucide-angular'
    import { cn } from '@/lib/utils'
    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 AwardEntry {
      body: string
      category: string
      period: string
    }
    
    // Body, category, and period on every entry. A badge without a period is a
    // badge that could be six years old.
    const awards: AwardEntry[] = [
      { body: 'G2', category: 'Leader — Analytics Platforms', period: 'Winter 2026' },
      { body: 'G2', category: 'Best Usability — Mid-Market', period: 'Winter 2026' },
      { body: 'Capterra', category: 'Best Value — Business Intelligence', period: '2025' },
      { body: 'TrustRadius', category: 'Top Rated — Data Governance', period: '2025' },
      { body: 'Product Hunt', category: '#1 Product of the Day', period: 'Mar 2025' },
      { body: 'SaaS Awards', category: 'Best Data Product, shortlisted', period: '2025' },
    ]
    
    @Component({
      changeDetection: ChangeDetectionStrategy.Eager,
      selector: 'ui-ratings-award-wall, [ui-ratings-award-wall]',
      standalone: true,
      // The block renders its own root <section>: keep this wrapper out of the layout.
      host: { '[attr.class]': '"contents"' },
      imports: [
        LucideAngularModule,
        UiBadgeComponent,
        UiButtonComponent,
        UiCardComponent,
        UiCardContentComponent,
        UiSeparatorComponent,
      ],
      template: `
        <section data-slot="ratings-award-wall" [class]="rootClass">
          <div class="mx-auto max-w-6xl px-6 py-20 lg:py-28">
            <div class="flex flex-wrap items-end justify-between gap-6">
              <div class="max-w-2xl">
                <span ui-badge variant="secondary">Recognition</span>
                <h2 class="mt-4 text-3xl font-semibold tracking-tight sm:text-4xl">Awarded, with the period attached</h2>
                <p class="text-muted-foreground mt-3 text-lg">
                  Every entry names who gave it, for what, and when. Nothing here is older than a year unless it says so.
                </p>
              </div>
              <button ui-button variant="outline">See the review profiles</button>
            </div>
    
            <div class="mt-10 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
              @for (award of awards; track award.body + award.category) {
                <div ui-card>
                  <div ui-card-content class="flex h-full flex-col p-5">
                    <div class="flex items-center gap-3">
                      <span
                        class="border-border text-muted-foreground flex size-9 shrink-0 items-center justify-center rounded-lg border"
                        aria-hidden="true"
                      >
                        <lucide-icon [img]="Award" class="size-4" />
                      </span>
                      <p class="text-sm font-semibold">{{ award.body }}</p>
                    </div>
                    <ui-separator class="my-4" />
                    <p class="text-sm leading-snug">{{ award.category }}</p>
                    <p class="text-muted-foreground mt-auto pt-3 font-mono text-xs">{{ award.period }}</p>
                  </div>
                </div>
              }
            </div>
          </div>
        </section>
      `,
    })
    export class UiRatingsAwardWallComponent {
      protected readonly Award = Award
      protected readonly awards = awards
    
      @Input('class') className?: string
    
      get rootClass(): string {
        return cn('bg-background', this.className)
      }
    }
    
  • src/app/components/blocks/ratings-award-wall/index.ts0.1 kB

Raw manifest:https://uipkge.dev/r/angular/ratings-award-wall.json