name: angular-frontend
description: Build and implement Angular 18 standalone components, TypeScript services with Signals and RxJS, routing with guards, and Tailwind CSS styling for Photo Map MVP. Use when creating, developing, or implementing TypeScript components, services, guards, forms, HTTP calls, map integration (Leaflet.js), or responsive UI layouts with Tailwind utilities. File types: .ts, .html, .css, .scss
allowed-tools: Read, Write, Edit, Grep, Glob, Bash
Angular Frontend Development - Photo Map MVP
Project Context
Photo Map MVP - Single Page Application (SPA) for managing photos with geolocation.
Frontend Stack:
- Angular: 18.2.0+ (standalone components, NO NgModules!)
- TypeScript: 5.5.2+ (strict mode)
- Styling: Tailwind CSS 3.4.17 (NOT v4 - Angular 18 incompatibility!)
- Map: Leaflet.js 1.9.4 + marker clustering
- State: RxJS 7.8.0 (BehaviorSubject pattern, no NgRx)
- Build: Angular CLI 18.2.0 (esbuild)
Core Features:
- Authentication: Login/Register with JWT storage, route guards
- Gallery: Responsive grid with lazy loading, rating, filtering
- Map View: Leaflet integration with GPS markers, popups, clustering
- Admin Panel: User management (ADMIN role only)
Key Constraints:
- Standalone components ONLY - NO NgModules anywhere!
- Tailwind 3.4.17 - NOT 4.x (incompatibility with Angular 18)
- inject() function - NOT constructor injection (modern Angular 18)
- Signals - reactive state (Angular 16+)
- BehaviorSubject - service state management (no NgRx)
Architecture Principles
Standalone Components
ALL components MUST be standalone (standalone: true). Explicitly import dependencies in imports array. NO @NgModule anywhere.
Check: references/angular-patterns.md for complete patterns.
State Management Strategy
Decision Tree:
- Component-local state → Use Signals (
signal(), computed(), effect())
- Shared state (cross-component) → Use BehaviorSubject in Services
Pattern: private BehaviorSubject → public Observable → Component subscribes
Check: references/state-management.md for detailed patterns.
Dependency Injection
Use inject() function (modern Angular 18), NOT constructor injection. Make all injected services readonly.
Example: private readonly photoService = inject(PhotoService);
When to Use What
Signals vs BehaviorSubject
| Use Case |
Solution |
| Component-local state (counters, UI flags, filters) |
Signals |
| Computed values (derived state) |
Signals (computed()) |
| Shared state (cross-component, services) |
BehaviorSubject |
| Async operations (HTTP, timers) |
BehaviorSubject |
| Complex RxJS pipelines |
BehaviorSubject |
Smart vs Dumb Components
| Type |
Characteristics |
| Smart (Container) |
Inject services, manage state, business logic, fetch data |
| Dumb (Presentational) |
NO service injection, @Input/@Output only, pure presentation |
Check: references/component-patterns.md for detailed examples.
Implementation Workflows
Creating Component
- Use checklist:
templates/component-template.md
- Standalone setup:
@Component({ standalone: true })
- Import dependencies:
CommonModule, RouterLink, child components
- Dependency injection: Use
inject(), make services readonly
- State: Signals for local state, BehaviorSubject consumption for shared state
- Template: Use @if, @for (NOT *ngIf, *ngFor), add
data-testid attributes
- Examples:
- Smart component →
examples/photo-gallery.component.ts
- Dumb component →
examples/photo-card.component.ts
Check: references/component-patterns.md for Smart vs Dumb patterns.
Creating Service
- Use checklist:
templates/service-template.md
- State management:
- Private:
private readonly itemsSubject = new BehaviorSubject<T>([])
- Public:
readonly items$ = itemsSubject.asObservable()
- HTTP methods: All return
Observable<T> with explicit types
- Error handling: Use
catchError, log errors, transform to user-friendly messages
- Example:
examples/photo.service.ts (BehaviorSubject + HTTP)
Check: references/service-patterns.md for HTTP patterns and interceptors.
Routing Setup
- Use checklist:
templates/route-template.md
- Configure routes:
app.routes.ts with flat Routes array
- Functional guards: Use
CanActivateFn, inject services with inject()
- Register:
provideRouter(routes) in app.config.ts
- Examples:
- Routes →
examples/app.routes.ts
- Guards →
examples/auth.guard.ts
Check: references/angular-patterns.md for routing and guards.
Patterns and Best Practices
- TypeScript quality: Check
references/typescript-quality.md (readonly, const, strict mode)
- RxJS patterns: Check
references/rxjs-patterns.md (operators, async pipe, error handling)
- Tailwind CSS: Check
references/tailwind-patterns.md (utility-first, responsive, constraints)
- Leaflet integration: Check
references/leaflet-integration.md (map setup, markers, clustering)
- SOLID principles: Check
references/solid-principles.md (when complexity justifies it)
- Testing: Check
references/testing-patterns.md (Jasmine + Karma, test IDs)
- Responsive design: Check
references/responsive-design.md (mobile-first, touch-friendly)
Key Reminders
Critical Constraints:
- ✅ ALWAYS
standalone: true (NO NgModules!)
- ✅ Use
inject() NOT constructor injection
- ✅ Tailwind 3.4.17 (NOT 4 - incompatibility!)
- ✅
data-testid on all interactive elements (kebab-case)
- ✅
readonly for services, const for variables
- ✅ Explicit return types (TypeScript strict)
State Management:
- ✅ Signals → component-local state
- ✅ BehaviorSubject → service state (shared)
- ✅ Async pipe in templates (automatic cleanup)
Component Structure:
- ✅ Smart components: inject services, manage state
- ✅ Dumb components: @Input/@Output only
- ✅ Use @if, @for, @switch (NOT *ngIf, *ngFor)
Routing:
- ✅ Functional guards (
CanActivateFn)
- ✅ Return
true | false | UrlTree
- ✅ Use
inject() in guards
Quick Reference
Pattern Lookup
| Need |
Check |
| Angular patterns (standalone, control flow, inject) |
references/angular-patterns.md |
| State management (Signals vs BehaviorSubject) |
references/state-management.md |
| TypeScript quality (readonly, const, strict) |
references/typescript-quality.md |
| RxJS patterns (operators, async pipe) |
references/rxjs-patterns.md |
| Tailwind styling (utility-first, responsive) |
references/tailwind-patterns.md |
| Leaflet maps (setup, markers, clustering) |
references/leaflet-integration.md |
| Component patterns (Smart vs Dumb) |
references/component-patterns.md |
| Service patterns (HTTP, BehaviorSubject) |
references/service-patterns.md |
| SOLID principles |
references/solid-principles.md |
| Testing (Jasmine, Karma) |
references/testing-patterns.md |
| Responsive design (mobile-first, RWD) |
references/responsive-design.md |
Example Lookup
| Need |
Check |
| Smart component (with Signals + Services) |
examples/photo-gallery.component.ts |
| Dumb component (@Input/@Output) |
examples/photo-card.component.ts |
| Service (BehaviorSubject + HTTP) |
examples/photo.service.ts |
| Filter service (state management) |
examples/filter.service.ts |
| Map component (Leaflet integration) |
examples/map.component.ts |
| Functional guards |
examples/auth.guard.ts |
| Route configuration |
examples/app.routes.ts |
| TypeScript interfaces |
examples/photo.interface.ts |
| HTTP interceptors |
examples/jwt.interceptor.ts |
Template Lookup (Checklists)
| Need |
Check |
| Creating standalone component |
templates/component-template.md |
| Creating service with state |
templates/service-template.md |
| Routing + guards setup |
templates/route-template.md |
| Writing tests (Jasmine + Karma) |
templates/test-template.md |
1---2name: angular-frontend3description: Build and implement Angular 18 standalone components, TypeScript services with Signals and RxJS, routing with guards, and Tailwind CSS styling for Photo Map MVP. Use when creating, developing, or impl4---5
6---
7name: angular-frontend
8description: Build and implement Angular 18 standalone components, TypeScript services with Signals and RxJS, routing with guards, and Tailwind CSS styling for Photo Map MVP. Use when creating, developing, or implementing TypeScript components, services, guards, forms, HTTP calls, map integration (Leaflet.js), or responsive UI layouts with Tailwind utilities. File types: .ts, .html, .css, .scss
9allowed-tools: Read, Write, Edit, Grep, Glob, Bash
10---
11
12# Angular Frontend Development - Photo Map MVP
13
14## Project Context
15
16**Photo Map MVP** - Single Page Application (SPA) for managing photos with geolocation.
17
18**Frontend Stack:**
19- **Angular:** 18.2.0+ (standalone components, NO NgModules!)
20- **TypeScript:** 5.5.2+ (strict mode)
21- **Styling:** Tailwind CSS 3.4.17 (NOT v4 - Angular 18 incompatibility!)
22- **Map:** Leaflet.js 1.9.4 + marker clustering
23- **State:** RxJS 7.8.0 (BehaviorSubject pattern, no NgRx)
24- **Build:** Angular CLI 18.2.0 (esbuild)
25
26**Core Features:**
271. **Authentication:** Login/Register with JWT storage, route guards
282. **Gallery:** Responsive grid with lazy loading, rating, filtering
293. **Map View:** Leaflet integration with GPS markers, popups, clustering
304. **Admin Panel:** User management (ADMIN role only)
31
32**Key Constraints:**
33- **Standalone components ONLY** - NO NgModules anywhere!
34- **Tailwind 3.4.17** - NOT 4.x (incompatibility with Angular 18)
35- **inject() function** - NOT constructor injection (modern Angular 18)
36- **Signals** - reactive state (Angular 16+)
37- **BehaviorSubject** - service state management (no NgRx)
38
39---
40
41## Architecture Principles
42
43### Standalone Components
44
45ALL components MUST be standalone (`standalone: true`). Explicitly import dependencies in `imports` array. NO `@NgModule` anywhere.
46
47Check: `references/angular-patterns.md` for complete patterns.
48
49### State Management Strategy
50
51**Decision Tree:**
52- **Component-local state** → Use Signals (`signal()`, `computed()`, `effect()`)
53- **Shared state (cross-component)** → Use BehaviorSubject in Services
54
55**Pattern:** `private BehaviorSubject` → `public Observable` → Component subscribes
56
57Check: `references/state-management.md` for detailed patterns.
58
59### Dependency Injection
60
61Use `inject()` function (modern Angular 18), NOT constructor injection. Make all injected services `readonly`.
62
63Example: `private readonly photoService = inject(PhotoService);`
64
65---
66
67## When to Use What
68
69### Signals vs BehaviorSubject
70
71| Use Case | Solution |
72|----------|----------|
73| Component-local state (counters, UI flags, filters) | **Signals** |
74| Computed values (derived state) | **Signals** (`computed()`) |
75| Shared state (cross-component, services) | **BehaviorSubject** |
76| Async operations (HTTP, timers) | **BehaviorSubject** |
77| Complex RxJS pipelines | **BehaviorSubject** |
78
79### Smart vs Dumb Components
80
81| Type | Characteristics |
82|------|-----------------|
83| **Smart** (Container) | Inject services, manage state, business logic, fetch data |
84| **Dumb** (Presentational) | NO service injection, @Input/@Output only, pure presentation |
85
86Check: `references/component-patterns.md` for detailed examples.
87
88---
89
90## Implementation Workflows
91
92### Creating Component
93
941. **Use checklist:** `templates/component-template.md`
952. **Standalone setup:**
96 - `@Component({ standalone: true })`
97 - Import dependencies: `CommonModule`, `RouterLink`, child components
983. **Dependency injection:** Use `inject()`, make services `readonly`
994. **State:** Signals for local state, BehaviorSubject consumption for shared state
1005. **Template:** Use @if, @for (NOT *ngIf, *ngFor), add `data-testid` attributes
1016. **Examples:**
102 - Smart component → `examples/photo-gallery.component.ts`
103 - Dumb component → `examples/photo-card.component.ts`
104
105Check: `references/component-patterns.md` for Smart vs Dumb patterns.
106
107### Creating Service
108
1091. **Use checklist:** `templates/service-template.md`
1102. **State management:**
111 - Private: `private readonly itemsSubject = new BehaviorSubject<T>([])`
112 - Public: `readonly items$ = itemsSubject.asObservable()`
1133. **HTTP methods:** All return `Observable<T>` with explicit types
1144. **Error handling:** Use `catchError`, log errors, transform to user-friendly messages
1155. **Example:** `examples/photo.service.ts` (BehaviorSubject + HTTP)
116
117Check: `references/service-patterns.md` for HTTP patterns and interceptors.
118
119### Routing Setup
120
1211. **Use checklist:** `templates/route-template.md`
1222. **Configure routes:** `app.routes.ts` with flat Routes array
1233. **Functional guards:** Use `CanActivateFn`, inject services with `inject()`
1244. **Register:** `provideRouter(routes)` in `app.config.ts`
1255. **Examples:**
126 - Routes → `examples/app.routes.ts`
127 - Guards → `examples/auth.guard.ts`
128
129Check: `references/angular-patterns.md` for routing and guards.
130
131### Patterns and Best Practices
132
133- **TypeScript quality:** Check `references/typescript-quality.md` (readonly, const, strict mode)
134- **RxJS patterns:** Check `references/rxjs-patterns.md` (operators, async pipe, error handling)
135- **Tailwind CSS:** Check `references/tailwind-patterns.md` (utility-first, responsive, constraints)
136- **Leaflet integration:** Check `references/leaflet-integration.md` (map setup, markers, clustering)
137- **SOLID principles:** Check `references/solid-principles.md` (when complexity justifies it)
138- **Testing:** Check `references/testing-patterns.md` (Jasmine + Karma, test IDs)
139- **Responsive design:** Check `references/responsive-design.md` (mobile-first, touch-friendly)
140
141---
142
143## Key Reminders
144
145**Critical Constraints:**
146- ✅ ALWAYS `standalone: true` (NO NgModules!)
147- ✅ Use `inject()` NOT constructor injection
148- ✅ Tailwind 3.4.17 (NOT 4 - incompatibility!)
149- ✅ `data-testid` on all interactive elements (kebab-case)
150- ✅ `readonly` for services, `const` for variables
151- ✅ Explicit return types (TypeScript strict)
152
153**State Management:**
154- ✅ Signals → component-local state
155- ✅ BehaviorSubject → service state (shared)
156- ✅ Async pipe in templates (automatic cleanup)
157
158**Component Structure:**
159- ✅ Smart components: inject services, manage state
160- ✅ Dumb components: @Input/@Output only
161- ✅ Use @if, @for, @switch (NOT *ngIf, *ngFor)
162
163**Routing:**
164- ✅ Functional guards (`CanActivateFn`)
165- ✅ Return `true | false | UrlTree`
166- ✅ Use `inject()` in guards
167
168---
169
170## Quick Reference
171
172### Pattern Lookup
173
174| Need | Check |
175|------|-------|
176| Angular patterns (standalone, control flow, inject) | `references/angular-patterns.md` |
177| State management (Signals vs BehaviorSubject) | `references/state-management.md` |
178| TypeScript quality (readonly, const, strict) | `references/typescript-quality.md` |
179| RxJS patterns (operators, async pipe) | `references/rxjs-patterns.md` |
180| Tailwind styling (utility-first, responsive) | `references/tailwind-patterns.md` |
181| Leaflet maps (setup, markers, clustering) | `references/leaflet-integration.md` |
182| Component patterns (Smart vs Dumb) | `references/component-patterns.md` |
183| Service patterns (HTTP, BehaviorSubject) | `references/service-patterns.md` |
184| SOLID principles | `references/solid-principles.md` |
185| Testing (Jasmine, Karma) | `references/testing-patterns.md` |
186| Responsive design (mobile-first, RWD) | `references/responsive-design.md` |
187
188### Example Lookup
189
190| Need | Check |
191|------|-------|
192| Smart component (with Signals + Services) | `examples/photo-gallery.component.ts` |
193| Dumb component (@Input/@Output) | `examples/photo-card.component.ts` |
194| Service (BehaviorSubject + HTTP) | `examples/photo.service.ts` |
195| Filter service (state management) | `examples/filter.service.ts` |
196| Map component (Leaflet integration) | `examples/map.component.ts` |
197| Functional guards | `examples/auth.guard.ts` |
198| Route configuration | `examples/app.routes.ts` |
199| TypeScript interfaces | `examples/photo.interface.ts` |
200| HTTP interceptors | `examples/jwt.interceptor.ts` |
201
202### Template Lookup (Checklists)
203
204| Need | Check |
205|------|-------|
206| Creating standalone component | `templates/component-template.md` |
207| Creating service with state | `templates/service-template.md` |
208| Routing + guards setup | `templates/route-template.md` |
209| Writing tests (Jasmine + Karma) | `templates/test-template.md` |