Documentation
This commit is contained in:
713
app/README.md
Normal file
713
app/README.md
Normal file
@@ -0,0 +1,713 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user