# Looking - Frontend Application

> **Ionic 3 / Angular 5 mobile application for browsing dating app profiles and stories**

This is the frontend mobile application for the "Looking" art project. Built with Ionic 3 and Angular 5, it provides an interactive interface for exploring user profiles, stories, and messages about modern gay dating culture.

---

## 📋 Table of Contents

- [Overview](#overview)
- [Tech Stack](#tech-stack)
- [Project Structure](#project-structure)
- [Pages & Components](#pages--components)
- [Services](#services)
- [Data Flow](#data-flow)
- [Development](#development)
- [Building](#building)
- [Troubleshooting](#troubleshooting)

---

## 🎯 Overview

The frontend is a **hybrid mobile application** that can run as:

- Web application (development mode on port 8100)
- iOS native app (requires Xcode)
- Android native app (requires Android Studio)

**Key Features:**

- Grid-based profile browsing (Tinder-like swipe interface)
- Detailed profile views with images and user stories
- Message threads with conversation history
- Story submission form ("Tell Your Story")
- Tab-based navigation
- Offline support with local JSON fallback

---

## 🛠 Tech Stack

| Technology          | Version | Purpose                                  |
| ------------------- | ------- | ---------------------------------------- |
| **Ionic Framework** | 3.9.2   | Hybrid mobile framework                  |
| **Angular**         | 5.0.3   | Component framework                      |
| **TypeScript**      | 2.4.2   | Type-safe JavaScript                     |
| **RxJS**            | 5.5.2   | Reactive programming                     |
| **@angular/http**   | 5.0.3   | HTTP client (deprecated, pre-HttpClient) |
| **ionic-swipe-all** | 1.2.0   | Swipe gesture library                    |
| **moment**          | 2.21.0  | Date/time formatting                     |
| **@ionic/storage**  | 2.1.3   | Local storage abstraction                |
| **ionicons**        | 3.0.0   | Icon library                             |

**Build Tool**: `@ionic/app-scripts` 3.2.4 (Ionic's custom webpack wrapper)

---

## 📁 Project Structure

```
app/
├── src/
│   ├── app/                          # Root application module
│   │   ├── app.component.ts          # Root component (title: "Urnings")
│   │   ├── app.module.ts             # Main NgModule with declarations
│   │   ├── app.html                  # Root template
│   │   ├── app.scss                  # Global styles
│   │   └── main.ts                   # Bootstrap entry point
│   │
│   ├── pages/                        # Page components (routable views)
│   │   ├── tabs/                     # Tab navigation container
│   │   │   ├── tabs.ts               # TabsPage component
│   │   │   └── tabs.html             # Tab layout (3 tabs)
│   │   │
│   │   ├── grid/                     # Profile grid view (main browse page)
│   │   │   ├── grid.ts               # Grid logic with swipe handling
│   │   │   ├── grid.html             # Grid layout with profile cards
│   │   │   └── grid.scss             # Grid styles
│   │   │
│   │   ├── profile/                  # Detailed profile view
│   │   │   ├── profile.ts            # Profile display logic
│   │   │   ├── profile.html          # Profile template (name, age, about, pics)
│   │   │   └── profile.scss          # Profile styles
│   │   │
│   │   ├── chat/                     # Individual conversation view
│   │   │   ├── chat.ts               # Chat message display
│   │   │   ├── chat.html             # Message thread UI
│   │   │   └── chat.scss             # Chat bubble styles
│   │   │
│   │   ├── messages/                 # Message list/inbox view
│   │   │   ├── messages.ts           # Message list logic
│   │   │   ├── messages.html         # List of conversations
│   │   │   └── messages.scss         # Message list styles
│   │   │
│   │   ├── users/                    # User list view
│   │   │   ├── users.ts              # User list logic
│   │   │   ├── users.html            # User grid/list
│   │   │   └── users.scss            # User list styles
│   │   │
│   │   ├── lightbox/                 # Full-screen image viewer
│   │   │   ├── lightbox.ts           # Image zoom/pan logic
│   │   │   ├── lightbox.html         # Fullscreen image display
│   │   │   └── lightbox.scss         # Lightbox styles
│   │   │
│   │   ├── information/              # Info/about page
│   │   │   ├── information.ts        # Static info page
│   │   │   ├── information.html      # Project information
│   │   │   └── information.scss      # Info page styles
│   │   │
│   │   └── tell/                     # Story submission form
│   │       ├── tell.ts               # Form submission logic
│   │       ├── tell.html             # Story submission form
│   │       └── tell.scss             # Form styles
│   │
│   ├── services/                     # Shared services
│   │   └── profiles.ts               # ProfileService for data management
│   │
│   ├── theme/                        # Global theme configuration
│   │   └── variables.scss            # Ionic theme variables
│   │
│   ├── assets/                       # Static assets
│   │   ├── data/                     # Local JSON data files (fallback)
│   │   │   ├── profiles.json         # All profiles
│   │   │   ├── profiles initial.json # Initial seed data
│   │   │   └── cruises.json          # Additional data
│   │   ├── icon/                     # App icons
│   │   ├── images/                   # Profile, message images
│   │   │   ├── profile/              # Profile photos
│   │   │   ├── message/              # Message attachments
│   │   │   └── cruise/               # Cruise-related images
│   │   └── imgs/                     # UI images and icons
│   │
│   ├── index.html                    # Main HTML entry
│   ├── manifest.json                 # PWA manifest
│   └── service-worker.js             # Service worker for offline support
│
├── www/                              # Build output directory
│   ├── build/                        # Compiled JS/CSS bundles
│   │   ├── main.js                   # Application code
│   │   ├── vendor.js                 # Third-party libraries
│   │   ├── polyfills.js              # Browser polyfills
│   │   └── main.css                  # Compiled styles
│   └── assets/                       # Copied static assets
│
├── package.json                      # Dependencies and scripts
├── ionic.config.json                 # Ionic CLI configuration
├── tsconfig.json                     # TypeScript compiler config
├── tslint.json                       # TSLint rules (deprecated)
└── .editorconfig                     # Editor formatting rules
```

---

## 📄 Pages & Components

### TabsPage (`pages/tabs/`)

**Root navigation container** with three tabs:

```typescript
// tabs.ts - Tab configuration
tabs = [
  { root: GridPage, tabTitle: "Grid", tabIcon: "grid" },
  { root: UsersPage, tabTitle: "Users", tabIcon: "people" },
  { root: MessagesPage, tabTitle: "Messages", tabIcon: "chatboxes" },
];
```

### GridPage (`pages/grid/`)

**Main profile browsing interface** - Tinder-like grid:

- Displays profile thumbnails in grid layout
- Supports swipe gestures (using `ionic-swipe-all`)
- Taps open detailed profile view
- Loads profiles from ProfileService
- Falls back to local JSON if API unavailable

**Key Features:**

- Swipe left/right for navigation
- Pull-to-refresh
- Infinite scroll
- Click thumbnail → ProfilePage

### ProfilePage (`pages/profile/`)

**Detailed profile view** with:

- Profile photo (large detail image)
- Name, age, location
- "About" section with user story
- Multiple photos in gallery
- Message thread (if profile has messages)
- Navigation to previous/next profile

**Navigation:**

- Receives profile ID via NavParams
- "Next" and "Previous" buttons
- Photo gallery opens LightboxPage

### ChatPage (`pages/chat/`)

**Message thread view**:

- Displays conversation history
- Question/answer format
- User responses vs. interviewer questions
- Image attachments supported
- Timestamps with moment.js

**Message Types:**

- `isUser: false` → Questions (left-aligned)
- `isUser: true` → User responses (right-aligned)

### MessagesPage (`pages/messages/`)

**Inbox/conversation list**:

- Shows all profiles with messages
- Displays message preview
- Unread indicators
- Tap to open ChatPage with full thread

### UsersPage (`pages/users/`)

**User list view**:

- Alternative view to grid
- List format with thumbnails
- Quick access to profiles
- Filter/search options (if implemented)

### LightboxPage (`pages/lightbox/`)

**Full-screen image viewer**:

- Zoom and pan gestures
- Swipe between photos
- Close button returns to profile
- Supports pinch-to-zoom

### InformationPage (`pages/information/`)

**Static information page**:

- About the art project
- Artist statement
- Project goals
- Credits and acknowledgments

### TellPage (`pages/tell/`)

**Story submission form**:

- Users can submit their own stories
- Form fields: name, age, location, story
- Photo upload
- Submission sends to API (if connected)

---

## 🔌 Services

### ProfileService (`services/profiles.ts`)

**Central data management service** for profiles.

**Endpoints:**

```typescript
endpoint: "http://localhost:27017/urnings/profiles"; // Primary API
fallback: "assets/data/profiles.json"; // Local fallback
epSubmitted: "/submitted"; // Submitted profiles
epVerified: "/verified"; // Verified profiles
```

**Methods:**

```typescript
load(); // Load all profiles
loadSubmitted(); // Load submitted (pending) profiles
loadVerified(); // Load verified (approved) profiles
getProfiles(); // Get cached profiles
getProfileById(id); // Get specific profile
getNextProfile(id); // Navigate to next profile
getPreviousProfile(id); // Navigate to previous
```

**Data Flow:**

1. Tries to fetch from API endpoint
2. On error, falls back to local `assets/data/profiles.json`
3. Caches data in memory
4. Builds ID→index map for navigation

**Fallback Behavior:**

```typescript
doGetRequest(endpoint, resolve, type) {
  this.http.get(endpoint).subscribe(
    (data) => { /* Use API data */ },
    (error) => {
      // API failed → use local JSON
      this.doGetRequest(this.fallback, resolve, type);
    }
  );
}
```

---

## 🔄 Data Flow

### Profile Loading Flow

```mermaid
graph TD
    A[GridPage loads] --> B{ProfileService.load}
    B --> C[Try API: http://localhost:27017/urnings/profiles]
    C --> D{API Success?}
    D -->|Yes| E[Store profiles in memory]
    D -->|No| F[Fallback to assets/data/profiles.json]
    F --> E
    E --> G[Build ID-to-index map]
    G --> H[Return profiles to GridPage]
    H --> I[Display grid of thumbnails]
    I --> J[User taps profile]
    J --> K[Navigate to ProfilePage with ID]
    K --> L[ProfilePage fetches profile from service]
    L --> M[Display full profile details]
```

### Message Loading Flow

```mermaid
graph TD
    A[ProfilePage loads] --> B[Get profile by ID]
    B --> C{Profile has messages?}
    C -->|Yes| D[Extract messages array]
    C -->|No| E[Show 'No messages']
    D --> F[Display in ChatPage]
    F --> G[Format with moment.js]
    G --> H[Render question/answer pairs]
```

---

## 💻 Development

### Start Dev Server

```bash
# From project root
npm run dev:app

# Or from app directory
cd app
ionic serve --host=0.0.0.0 --port=8100
```

**Access**: http://localhost:8100

### Live Reload

Ionic's dev server watches for file changes and automatically:

- Recompiles TypeScript
- Rebuilds SCSS
- Reloads browser
- Preserves dev tools open

### Chrome DevTools

Open Chrome DevTools to:

- Inspect components
- Debug TypeScript (source maps enabled)
- Test responsive layouts
- Simulate mobile devices
- Monitor network requests

### API Configuration

To switch between local and remote API:

**Edit `services/profiles.ts`:**

```typescript
// Local API (backend running on port 3069)
endpoint: "http://localhost:3069/profiles";

// Remote API (production)
endpoint: "https://api.pfosi.mifi.dev/profiles";

// Fallback (always local)
fallback: "assets/data/profiles.json";
```

---

## 🏗️ Building

### Development Build

```bash
npm run build
# or
ionic build
```

Output: `www/` directory

### Production Build

```bash
ionic build --prod
```

**Optimizations:**

- Minification
- Tree shaking
- Ahead-of-time (AOT) compilation
- CSS purging
- Source map generation (optional)

### Build for Mobile Platforms

**iOS**:

```bash
ionic cordova build ios --prod --release
# Requires Xcode and iOS development certificates
```

**Android**:

```bash
ionic cordova build android --prod --release
# Requires Android Studio and signing keys
```

**Note**: Mobile builds require additional Cordova setup not covered here.

---

## 🔧 Troubleshooting

### `node-sass` Build Failed

**Error:**

```
Error: `gyp` failed with exit code: 1
Module 'node-sass' not found
```

**Solution:**

```bash
# node-sass requires Python 2.7 (included in DevContainer)
# If running locally:
npm rebuild node-sass --force

# Or use legacy peer deps
npm install --legacy-peer-deps
```

**Why?** `node-sass` is a native module that requires Python 2.7 and build tools. The DevContainer includes these dependencies via symlinks.

---

### Peer Dependency Warnings

**Error:**

```
npm WARN ERESOLVE overriding peer dependency
```

**Solution:**

```bash
# Use legacy peer dependency resolution (npm 7+)
npm install --legacy-peer-deps
```

**Why?** Ionic 3 and Angular 5 were built before npm 7's strict peer dependency checking. The `--legacy-peer-deps` flag uses npm 6 behavior.

---

### Module Not Found Errors

**Error:**

```
Error: Cannot find module '@angular/core'
```

**Solution:**

```bash
# Remove node_modules and reinstall
rm -rf node_modules package-lock.json
npm install --legacy-peer-deps
```

---

### JavaScript Heap Out of Memory

**Error:**

```
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed
```

**Solution:**

```bash
# Increase Node.js memory limit
export NODE_OPTIONS="--max-old-space-size=4096"
npm run ionic:serve
```

---

### Ionic Serve Port Already in Use

**Error:**

```
Error: Port 8100 is already in use
```

**Solution:**

```bash
# Find process using port 8100
lsof -i :8100

# Kill the process
kill -9 <PID>

# Or use different port
ionic serve --port=8101
```

---

### TypeScript Compilation Errors

**Error:**

```
Error: TS2304: Cannot find name 'Promise'
```

**Solution:**

```bash
# Verify TypeScript version matches project
npm install typescript@2.4.2 --save-dev --save-exact
```

**Check `tsconfig.json`:**

```json
{
  "compilerOptions": {
    "lib": ["es2015", "dom"],
    "target": "es5"
  }
}
```

---

### CORS Errors in Browser

**Error:**

```
Access to XMLHttpRequest at 'http://localhost:3069/profiles' blocked by CORS policy
```

**Solution:**

**Option 1**: Backend already allows all origins:

```javascript
// backend/src/app.js
res.header("Access-Control-Allow-Origin", "*");
```

**Option 2**: Use Ionic's proxy (for dev server):

**Edit `ionic.config.json`:**

```json
{
  "proxies": [
    {
      "path": "/api",
      "proxyUrl": "http://localhost:3069"
    }
  ]
}
```

**Update service:**

```typescript
endpoint: "/api/profiles"; // Proxied through dev server
```

---

### Images Not Loading

**Error:**

```
404 Not Found: http://localhost:8100/assets/images/profile/john.png
```

**Solutions:**

1. **Verify image exists:**

   ```bash
   ls -la src/assets/images/profile/
   ```

2. **Check path in data:**

   ```json
   // Should be relative to assets/images/
   "pic": {
     "thumb": "profile/john_thumbnail.png",  // ✅ Correct
     "detail": "/profile/john_detail.png"    // ❌ Leading slash breaks it
   }
   ```

3. **Rebuild to copy assets:**
   ```bash
   ionic build
   ```

---

### Service Worker Issues (Offline Mode)

**Problem**: Stale data cached, changes not appearing

**Solution:**

```bash
# Clear service worker cache in Chrome DevTools
Application → Storage → Clear site data

# Or disable service worker during development
# Comment out service worker registration in index.html
```

---

### Ionic CLI Not Found

**Error:**

```
ionic: command not found
```

**Solution:**

```bash
# Install Ionic CLI globally (included in DevContainer)
npm install -g @ionic/cli

# Verify installation
ionic --version
```

---

## 📚 Additional Resources

- **Ionic 3 Documentation**: https://ionicframework.com/docs/v3/
- **Angular 5 Documentation**: https://v5.angular.io/docs
- **TypeScript Documentation**: https://www.typescriptlang.org/docs/handbook/basic-types.html
- **RxJS 5 Documentation**: https://rxjs-dev.firebaseapp.com/api

---

## 🔗 Related Documentation

- [Root README](../README.md) - Project overview and quick start
- [Backend README](../backend/README.md) - API server documentation
- [API Reference](../backend/API.md) - REST API endpoints
- [Database Schema](../backend/SCHEMA.md) - MongoDB collections
- [DevContainer Guide](../.devcontainer/README.md) - Development environment
- [Deployment Guide](../DEPLOYMENT.md) - Production deployment

---

**Need Help?** Check the [root troubleshooting section](../README.md#troubleshooting) or backend documentation for API-related issues.
