AI Skill Report Card

Implementing Angular Retail Banking

A-82·Mar 29, 2026·Source: Web
15 / 15
TypeScript
import { Component, inject } from '@angular/core'; import { CommonModule } from '@angular/common'; import { Button, ListItem, Loader } from '@shared/ui'; import { SomeQuery } from '@shared/api'; @Component({ selector: 'app-component-name', imports: [CommonModule, Button, ListItem, Loader], templateUrl: './component-name.html', styleUrl: './component-name.css', }) export class ComponentName { private someQuery = inject(SomeQuery); data = this.someQuery.getDataQuery(); handleAction() { // Implementation } }
Recommendation
Remove the extensive design system utilities section - Claude knows CSS utilities and this over-explains basics
13 / 15

Progress:

  • Create component folder with .ts, .html, .css, .spec.ts files
  • Import required shared UI components from @shared/ui
  • Set up state management with TanStack Query and signals
  • Build template using utility classes and control flow syntax
  • Apply design system tokens and spacing utilities
  • Test component with loading/error/success states
Recommendation
Compress the workflow section into a simpler checklist without explanatory text

Spacing (4px base, 16 levels)

CSS
.m-1 to .m-16 /* margin: 4px to 88px */ .p-1 to .p-16 /* padding: 4px to 88px */ .gap-4 /* 16px gap */

Colors

CSS
.bg-accent-500 /* Primary blue */ .text-secondary /* Muted text */ .text-green-500 /* Success */ .text-red-500 /* Error */

Layout

HTML
<div class="grid-container max-w-full"> <div class="w-5">5/12 width</div> <div class="w-7">7/12 width</div> </div> <div class="flex justify-center align-items-center gap-4"> <!-- Flexbox content --> </div>
18 / 20

Example 1: Data List Component

Input: Create a component showing account transactions with loading state

Output:

TypeScript
// account-transactions.ts import { Component, inject } from '@angular/core'; import { ListItem, Loader } from '@shared/ui'; import { AccountsQuery } from '@shared/api'; @Component({ selector: 'app-account-transactions', imports: [ListItem, Loader], templateUrl: './account-transactions.html', styleUrl: './account-transactions.css', }) export class AccountTransactions { private accountsQuery = inject(AccountsQuery); transactions = this.accountsQuery.getTransactionsQuery(); }
HTML
<!-- account-transactions.html --> <div class="card p-4"> <h2 class="text-xl font-semibold mb-4">Recent Transactions</h2> @if (transactions.isLoading()) { <lib-loader variant="list" [rows]="5"></lib-loader> } @else { @for (transaction of transactions.data()?.content; track transaction.id) { <lib-list-item [heading]="transaction.description" [subheading]="transaction.date" [prefixIcon]="transaction.type === 'DEBIT' ? 'solar:arrow-right-up-linear' : 'solar:arrow-left-down-linear'" > <div slot="suffix"> <span [class]="transaction.type === 'DEBIT' ? 'text-red-500' : 'text-green-500'"> {{ transaction.amount | currency:transaction.currency:'symbol':'1.2-2':'fr' }} </span> </div> </lib-list-item> } } </div>

Example 2: Form Dialog Component

Input: Create a dialog for adding a new payee with form validation

Output:

TypeScript
// add-payee-dialog.ts import { Component, inject, signal } from '@angular/core'; import { DialogComponent, Button, Input } from '@shared/ui'; import { PayeesQuery } from '@shared/api'; @Component({ selector: 'app-add-payee-dialog', imports: [DialogComponent, Button, Input], templateUrl: './add-payee-dialog.html', styleUrl: './add-payee-dialog.css', }) export class AddPayeeDialog { private payeesQuery = inject(PayeesQuery); visible = signal(false); payeeData = signal({ name: '', accountNumber: '' }); createMutation = this.payeesQuery.CreatePayeeMutation(); handleSubmit() { this.createMutation.mutate(this.payeeData()); } }
HTML
<!-- add-payee-dialog.html --> <lib-dialog [(visible)]="visible"> <div class="bg-screen p-6 border-radius-2xl"> <h2 class="text-2xl font-semibold mb-6">Add New Payee</h2> <div class="flex flex-column gap-4"> <lib-input label="Payee Name" placeholder="Enter payee name" [(ngModel)]="payeeData().name" /> <lib-input label="Account Number" placeholder="Enter account number" [(ngModel)]="payeeData().accountNumber" /> <div class="flex gap-3 justify-end"> <lib-button label="Cancel" variant="outline" (onClick)="visible.set(false)" /> <lib-button label="Add Payee" variant="primary" [loading]="createMutation.isPending()" (onClick)="handleSubmit()" /> </div> </div> </div> </lib-dialog>
Recommendation
Add a third example showing error handling or edge case scenarios to demonstrate robustness
  • Use .css files, not .scss
  • Import shared UI components from @shared/ui path
  • Use inject() for dependency injection instead of constructor
  • Leverage utility classes before writing custom CSS
  • Use signals for reactive state management
  • Apply TanStack Query pattern for server state
  • Follow Angular 17+ control flow syntax (@if, @for, @switch)
  • Include proper TypeScript typing for component inputs/outputs
  • Use ::ng-deep sparingly, only for PrimeNG component overrides
  • Don't use SCSS - stick to CSS files
  • Don't import PrimeNG components directly - use shared wrappers
  • Don't use constructor-based DI - prefer inject()
  • Don't write custom spacing CSS - use utility classes (.p-4, .m-2)
  • Don't forget loading and error states in templates
  • Don't skip the .spec.ts test files
  • Don't use inline styles in component decorator
  • Don't create new color values - use design system tokens
0
Grade A-AI Skill Framework
Scorecard
Criteria Breakdown
Quick Start
15/15
Workflow
13/15
Examples
18/20
Completeness
19/20
Format
15/15
Conciseness
12/15