# Travlr Getaways — Module 6 Submission

Full stack MEAN application: Express + MongoDB backend with REST API, Angular SPA admin frontend.

## What's in this zip

```
travlr/
├── app.js                    Express entrypoint (with CORS for /api)
├── app_api/                  REST API: GET, POST, PUT, DELETE on /api/trips
│   ├── controllers/trips.js
│   ├── models/
│   └── routes/index.js
├── app_server/               Customer-facing website (Handlebars views)
├── app_admin/                Angular 22 admin SPA
│   ├── angular.json
│   ├── package.json
│   ├── tsconfig*.json
│   └── src/
│       ├── index.html
│       ├── main.ts
│       ├── app/
│       │   ├── app.component.{ts,html,css,spec.ts}
│       │   ├── app.config.ts
│       │   ├── app.routes.ts
│       │   ├── data/trips.ts
│       │   ├── models/trip.ts
│       │   ├── services/trip-data.service.ts
│       │   ├── trip-listing/        Lists trip cards + Add button
│       │   ├── trip-card/           Single card with Edit button
│       │   ├── add-trip/            Reactive form for creating
│       │   └── edit-trip/           Reactive form for updating
│       └── assets/{css,images}/
├── bin/www
├── data/trips.json
├── public/                   Static site assets (Express)
└── package.json
```

## How to run

### 1. Install dependencies (one time)

From the project root (where `package.json` sits):
```powershell
npm install
```

Then in `app_admin/`:
```powershell
cd app_admin
npm install
cd ..
```

### 2. Start MongoDB

Make sure your local MongoDB is running on the default port (27017). The Mongoose connection string is in `app_api/models/db.js`.

### 3. Start the Express backend

From the project root, in one PowerShell window:
```powershell
npm start
```

You should see "Mongoose connected to mongodb://127.0.0.1/travlr" and the server listening on port 3000.

### 4. Start the Angular dev server

In a second PowerShell window:
```powershell
cd app_admin
ng serve
```

When it prints "Application bundle generation complete", open your browser:
```
http://localhost:4200
```

You should see the Travlr Getaways Admin navbar, an Add Trip button, and the three reef trip cards (Gale Reef, Dawson's Reef, Claire's Reef).

## Verify the REST API with Postman

All four endpoints live at `http://localhost:3000/api/trips`:

| Method | URL                         | Purpose                          |
| ------ | --------------------------- | -------------------------------- |
| GET    | `/api/trips`                | List all trips                   |
| GET    | `/api/trips/:tripCode`      | Get one trip by its code         |
| POST   | `/api/trips`                | Add a new trip (JSON body)       |
| PUT    | `/api/trips/:tripCode`      | Update an existing trip          |
| DELETE | `/api/trips/:tripCode`      | Delete a trip                    |

Example POST body (raw JSON, application/json):
```json
{
  "code": "TEST20260608",
  "name": "Postman Test Trip",
  "length": "3 nights / 4 days",
  "start": "2026-07-15T08:00:00Z",
  "resort": "Postman Resort, 4 stars",
  "perPerson": "899.00",
  "image": "reef1.jpg",
  "description": "<p>Test trip added via Postman.</p>"
}
```

## End-to-end test through the SPA (for screenshots)

1. **Card listing screenshot.** Open localhost:4200, click Add Trip, fill the form with a unique trip code, save. The page returns to the listing showing your new trip alongside the three reefs.
2. **Edit screen screenshot.** Click Edit Trip on any card. The form loads with that trip's existing values populated.
3. **Update screen screenshot.** Change one field, click Save. The listing returns showing the updated values.

## Tech notes (for the grader and for future-you)

- **Angular 22, zoneless change detection.** `app.config.ts` uses `provideZonelessChangeDetection()`. The trip list uses a `WritableSignal<Trip[]>` so updates from HTTP responses trigger renders without zone.js.
- **Native control flow.** Templates use `@for` and `@if` (Angular 17+ native syntax) instead of `*ngFor`/`*ngIf`, so no `CommonModule` juggling.
- **Schematics override** in `angular.json` keeps `.component.ts` / `.service.ts` naming for future `ng generate` calls (matches SNHU guide conventions).
- **Asset paths** in `angular.json` include both `public/` (for favicon and Express-shared assets) and `src/assets/` (for SPA-only images and CSS).
- **Date format fix** in `edit-trip.component.ts` slices the ISO date returned by the API to `yyyy-MM-dd` before patching the form, so the `<input type="date">` field populates correctly.

## Troubleshooting

- **CORS error in the browser console** → confirm `app.js` was loaded with the CORS middleware (search for `Access-Control-Allow-Methods`) and that you restarted Express after editing.
- **`npm install` complains about peer dependencies in `app_admin/`** → try `npm install --legacy-peer-deps`. If still failing, re-run `ng new travlr-admin --defaults=true --directory app_admin_fresh`, copy `app_admin_fresh/package.json` over `app_admin/package.json`, delete `app_admin_fresh`, and re-run `npm install`.
- **`ng serve` reports "module not found"** → run `npm install` again inside `app_admin/`.
- **Trip cards don't appear but console says "There are 3 trips available"** → backend is fine, but change detection isn't firing; verify `app.config.ts` has `provideZonelessChangeDetection()` and `trip-listing.component.ts` uses `signal<Trip[]>([])` with `this.trips.set(value)`.
