Little tweaks to make it work... In a devcontainer anyway....

This commit is contained in:
2025-07-25 21:32:20 -03:00
parent 9eb293ccb1
commit f17c0d08a1
110 changed files with 10672 additions and 1246 deletions

View File

@@ -1,13 +1,21 @@
FROM node:18-bullseye FROM node:14-bullseye
# Install additional tools including Ionic CLI # Install additional tools including Ionic CLI and build dependencies for older projects
RUN apt-get update && apt-get install -y \ RUN apt-get update && apt-get install -y \
git \ git \
curl \ curl \
vim \ vim \
mongodb-clients \ python2.7 \
python2.7-dev \
build-essential \
&& ln -sf /usr/bin/python2.7 /usr/bin/python \
&& ln -sf /usr/bin/python2.7 /usr/bin/python2 \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# Install MongoDB shell via npm (works on all architectures)
# Note: mongosh requires Node 18+, but we're using Node 14 for legacy compatibility
# We'll use the mongo command from the mongo container instead
# Install global npm packages for development # Install global npm packages for development
RUN npm install -g \ RUN npm install -g \
@ionic/cli \ @ionic/cli \
@@ -18,17 +26,18 @@ RUN npm install -g \
prettier prettier
# Set working directory # Set working directory
WORKDIR /workspaces/PfosiLooking WORKDIR /workspaces/PfosiLooking-monorepo
# Copy package files for dependency caching # Copy package files for dependency caching
COPY package*.json ./ COPY package*.json ./
COPY app/package*.json ./app/ COPY app/package*.json ./app/
COPY backend/package*.json ./backend/ COPY backend/package*.json ./backend/
# Install dependencies # Install dependencies separately to avoid node-sass issues during build
RUN npm install # We'll install them after container starts
RUN cd app && npm install # RUN npm install
RUN cd backend && npm install # RUN cd app && npm install
# RUN cd backend && npm install
# Keep container running # Keep container running
CMD ["sleep", "infinity"] CMD ["sleep", "infinity"]

View File

@@ -2,11 +2,11 @@
"name": "PfosiLooking Full Stack", "name": "PfosiLooking Full Stack",
"dockerComposeFile": "docker-compose.yml", "dockerComposeFile": "docker-compose.yml",
"service": "app", "service": "app",
"workspaceFolder": "/workspaces/PfosiLooking", "workspaceFolder": "/workspaces/PfosiLooking-monorepo",
"shutdownAction": "stopCompose", "shutdownAction": "stopCompose",
"features": { "features": {
"ghcr.io/devcontainers/features/node:1": { "ghcr.io/devcontainers/features/node:1": {
"version": "18" "version": "14"
}, },
"ghcr.io/devcontainers/features/git:1": {}, "ghcr.io/devcontainers/features/git:1": {},
"ghcr.io/devcontainers/features/github-cli:1": {} "ghcr.io/devcontainers/features/github-cli:1": {}
@@ -28,7 +28,7 @@
"editor.formatOnSave": true, "editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode", "editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": { "editor.codeActionsOnSave": {
"source.fixAll.eslint": true "source.fixAll.eslint": "explicit"
}, },
"emmet.includeLanguages": { "emmet.includeLanguages": {
"javascript": "javascriptreact" "javascript": "javascriptreact"
@@ -55,6 +55,6 @@
"onAutoForward": "notify" "onAutoForward": "notify"
} }
}, },
"postCreateCommand": "npm install && cd app && npm install && cd ../backend && npm install", "postCreateCommand": ".devcontainer/postCreateCommand.sh",
"postStartCommand": "npm run dev:all" "postStartCommand": "echo 'DevContainer ready! Run npm run dev:all to start development.'"
} }

View File

@@ -7,8 +7,8 @@ services:
dockerfile: .devcontainer/Dockerfile dockerfile: .devcontainer/Dockerfile
volumes: volumes:
- ../..:/workspaces:cached - ../..:/workspaces:cached
- /workspaces/PfosiLooking/app/node_modules - /workspaces/PfosiLooking-monorepo/app/node_modules
- /workspaces/PfosiLooking/backend/node_modules - /workspaces/PfosiLooking-monorepo/backend/node_modules
command: sleep infinity command: sleep infinity
environment: environment:
- NODE_ENV=development - NODE_ENV=development

View File

@@ -0,0 +1,31 @@
#!/bin/bash
set -e
echo "Setting up PfosiLooking monorepo dependencies..."
echo "Using Node version: $(node --version)"
# Install root dependencies first
echo "Installing root dependencies..."
npm install
echo "Installing backend dependencies..."
cd backend && npm install
cd ..
echo "Installing app dependencies (Ionic 3 with legacy packages)..."
cd app
# For Node 14 and older Ionic 3 projects, we need special handling
echo "Installing with legacy peer dependencies support..."
if npm install --legacy-peer-deps; then
echo "App dependencies installed successfully!"
else
echo "Standard install failed, trying alternative approach..."
# Try with force flag as last resort for very old packages
npm install --legacy-peer-deps --force
fi
cd ..
echo "All dependencies installed successfully!"
echo "You can now start development with: npm run dev:all"

View File

@@ -1,132 +0,0 @@
kind: pipeline
type: docker
name: looking-fullstack
steps:
# Install dependencies for both apps
- name: install-root
image: node:18-alpine
commands:
- npm ci
- name: install-frontend
image: node:18-alpine
commands:
- cd app && npm ci
depends_on:
- install-root
- name: install-backend
image: node:18-alpine
commands:
- cd backend && npm ci
depends_on:
- install-root
# Linting
- name: lint-frontend
image: node:18-alpine
commands:
- cd app && npm run lint
depends_on:
- install-frontend
- name: lint-backend
image: node:18-alpine
commands:
- cd backend && npm run lint
depends_on:
- install-backend
# Testing
- name: test-frontend
image: node:18-alpine
commands:
- cd app && npm run test:ci
depends_on:
- install-frontend
- name: test-backend
image: node:18-alpine
commands:
- cd backend && npm test
depends_on:
- install-backend
# Build
- name: build-frontend
image: node:18-alpine
commands:
- cd app && npm run build
depends_on:
- lint-frontend
- test-frontend
# Docker builds
- name: docker-build-frontend
image: plugins/docker
settings:
registry: git.mifi.dev:12023
repo: git.mifi.dev:12023/mifi/pfosi-looking-frontend
username:
from_secret: docker_username
password:
from_secret: docker_password
tags:
- latest
- ${DRONE_COMMIT_SHA:0:8}
dockerfile: app/Dockerfile
context: app
depends_on:
- build-frontend
when:
branch:
- master
- main
- name: docker-build-backend
image: plugins/docker
settings:
registry: git.mifi.dev:12023
repo: git.mifi.dev:12023/mifi/pfosi-looking-backend
username:
from_secret: docker_username
password:
from_secret: docker_password
tags:
- latest
- ${DRONE_COMMIT_SHA:0:8}
dockerfile: backend/Dockerfile
context: backend
depends_on:
- lint-backend
- test-backend
when:
branch:
- master
- main
# Deploy both services
- name: deploy-stack
image: curlimages/curl
commands:
- curl -X POST $PORTAINER_WEBHOOK_URL
environment:
PORTAINER_WEBHOOK_URL:
from_secret: portainer_webhook_fullstack
depends_on:
- docker-build-frontend
- docker-build-backend
when:
branch:
- master
- main
trigger:
branch:
- master
- main
- develop
event:
- push
- pull_request

7172
app/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -33,7 +33,7 @@
"zone.js": "0.8.18" "zone.js": "0.8.18"
}, },
"devDependencies": { "devDependencies": {
"@ionic/app-scripts": "3.1.8", "@ionic/app-scripts": "3.2.4",
"typescript": "2.4.2" "typescript": "2.4.2"
}, },
"description": "Nick Pfosi's exploration at modern gay app-based meeting and dating" "description": "Nick Pfosi's exploration at modern gay app-based meeting and dating"

View File

Before

Width:  |  Height:  |  Size: 616 KiB

After

Width:  |  Height:  |  Size: 616 KiB

View File

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 141 KiB

View File

Before

Width:  |  Height:  |  Size: 370 KiB

After

Width:  |  Height:  |  Size: 370 KiB

View File

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 97 KiB

View File

Before

Width:  |  Height:  |  Size: 381 KiB

After

Width:  |  Height:  |  Size: 381 KiB

View File

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

View File

Before

Width:  |  Height:  |  Size: 469 KiB

After

Width:  |  Height:  |  Size: 469 KiB

View File

Before

Width:  |  Height:  |  Size: 139 KiB

After

Width:  |  Height:  |  Size: 139 KiB

View File

Before

Width:  |  Height:  |  Size: 748 KiB

After

Width:  |  Height:  |  Size: 748 KiB

View File

Before

Width:  |  Height:  |  Size: 143 KiB

After

Width:  |  Height:  |  Size: 143 KiB

View File

Before

Width:  |  Height:  |  Size: 600 KiB

After

Width:  |  Height:  |  Size: 600 KiB

View File

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 130 KiB

View File

Before

Width:  |  Height:  |  Size: 816 KiB

After

Width:  |  Height:  |  Size: 816 KiB

View File

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 120 KiB

View File

Before

Width:  |  Height:  |  Size: 746 KiB

After

Width:  |  Height:  |  Size: 746 KiB

View File

Before

Width:  |  Height:  |  Size: 221 KiB

After

Width:  |  Height:  |  Size: 221 KiB

View File

Before

Width:  |  Height:  |  Size: 422 KiB

After

Width:  |  Height:  |  Size: 422 KiB

View File

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

View File

Before

Width:  |  Height:  |  Size: 445 KiB

After

Width:  |  Height:  |  Size: 445 KiB

View File

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 117 KiB

View File

Before

Width:  |  Height:  |  Size: 358 KiB

After

Width:  |  Height:  |  Size: 358 KiB

View File

Before

Width:  |  Height:  |  Size: 424 KiB

After

Width:  |  Height:  |  Size: 424 KiB

View File

Before

Width:  |  Height:  |  Size: 427 KiB

After

Width:  |  Height:  |  Size: 427 KiB

View File

Before

Width:  |  Height:  |  Size: 466 KiB

After

Width:  |  Height:  |  Size: 466 KiB

View File

Before

Width:  |  Height:  |  Size: 372 KiB

After

Width:  |  Height:  |  Size: 372 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

Before

Width:  |  Height:  |  Size: 183 KiB

After

Width:  |  Height:  |  Size: 183 KiB

View File

Before

Width:  |  Height:  |  Size: 182 KiB

After

Width:  |  Height:  |  Size: 182 KiB

View File

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 194 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

Before

Width:  |  Height:  |  Size: 153 KiB

After

Width:  |  Height:  |  Size: 153 KiB

View File

Before

Width:  |  Height:  |  Size: 275 KiB

After

Width:  |  Height:  |  Size: 275 KiB

View File

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 75 KiB

View File

Before

Width:  |  Height:  |  Size: 406 KiB

After

Width:  |  Height:  |  Size: 406 KiB

View File

Before

Width:  |  Height:  |  Size: 624 KiB

After

Width:  |  Height:  |  Size: 624 KiB

View File

Before

Width:  |  Height:  |  Size: 573 KiB

After

Width:  |  Height:  |  Size: 573 KiB

View File

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

@@ -5,21 +5,35 @@
<ion-icon name="arrow-back"></ion-icon> <ion-icon name="arrow-back"></ion-icon>
</button> </button>
</ion-buttons> </ion-buttons>
<ion-title><img class="title-profile-avatar" [src]="'https://appsby.fitz.guru/urge/' + this.profile.details.pic.thumb" height="24" width="24"> {{this.profile.details.name}}</ion-title> <ion-title
><img
class="title-profile-avatar"
[src]="'/assets/' + this.profile.details.pic.thumb"
height="24"
width="24"
/>
{{this.profile.details.name}}</ion-title
>
</ion-toolbar> </ion-toolbar>
</ion-header> </ion-header>
<ion-content> <ion-content>
<ion-list> <ion-list>
<ion-item class="message-bubble" *ngFor="let message of this.profile.messages" [ngClass]="{ 'is-user': (message.isUser == true) }"> <ion-item
<img *ngIf="message.image" [src]="'https://appsby.fitz.guru/urge/' + message.image" (press)="showLightbox($event, message.image)"> class="message-bubble"
*ngFor="let message of this.profile.messages"
[ngClass]="{ 'is-user': (message.isUser == true) }"
>
<img
*ngIf="message.image"
[src]="'/assets/' + message.image"
(press)="showLightbox($event, message.image)"
/>
<p *ngIf="message.text != ''">{{message.text}}</p> <p *ngIf="message.text != ''">{{message.text}}</p>
</ion-item> </ion-item>
</ion-list> </ion-list>
</ion-content> </ion-content>
<ion-footer> <ion-footer>
<ion-toolbar> <ion-toolbar> </ion-toolbar>
</ion-toolbar>
</ion-footer> </ion-footer>

View File

@@ -1,45 +1,50 @@
import { Component } from '@angular/core'; import { Component } from "@angular/core";
import { DomSanitizer } from '@angular/platform-browser'; import { DomSanitizer } from "@angular/platform-browser";
import { NavController } from 'ionic-angular'; import { NavController } from "ionic-angular";
import { ChatPage } from '../chat/chat'; import { ChatPage } from "../chat/chat";
import { ProfileService } from '../../services/profiles'; import { ProfileService } from "../../services/profiles";
import { ProfilePage } from '../profile/profile'; import { ProfilePage } from "../profile/profile";
@Component({ @Component({
selector: 'page-grid', selector: "page-grid",
templateUrl: 'grid.html', templateUrl: "grid.html",
providers: [ ProfileService ] providers: [ProfileService],
}) })
export class GridPage { export class GridPage {
profiles: any; profiles: any;
tabNavEl: any; tabNavEl: any;
constructor(public navCtrl: NavController, public profileService: ProfileService, private _sanitizer: DomSanitizer) { constructor(
public navCtrl: NavController,
public profileService: ProfileService,
private _sanitizer: DomSanitizer
) {
profileService.loadVerified().then((data) => { profileService.loadVerified().then((data) => {
this.profiles = data; this.profiles = data;
console.debug('profiles: ', this.profiles); console.debug("profiles: ", this.profiles);
}); });
this.tabNavEl = document.querySelector('#tab-nav .tabbar'); this.tabNavEl = document.querySelector("#tab-nav .tabbar");
} }
ionViewWillEnter() { ionViewWillEnter() {
this.tabNavEl.style.display = 'flex'; this.tabNavEl.style.display = "flex";
} }
doTellStory() { doTellStory() {
this.navCtrl.push(TellYourStoryPage); // this.navCtrl.push(TellYourStoryPage);
} }
getBackgroundThumbnail(pics) { getBackgroundThumbnail(pics) {
return this._sanitizer.bypassSecurityTrustStyle('url(https://appsby.fitz.guru/urge/' + pics.thumb + ')'); return this._sanitizer.bypassSecurityTrustStyle(
"url(/assets/" + pics.thumb + ")"
);
} }
profilePressed(event, profile) { profilePressed(event, profile) {
if (profile.messages && profile.messages.length) { if (profile.messages && profile.messages.length) {
this.navCtrl.push(ChatPage, { this.navCtrl.push(ChatPage, {
profile: profile profile: profile,
}); });
} }
} }

View File

@@ -8,15 +8,20 @@
<ion-list> <ion-list>
<ng-container *ngFor="let profile of profiles"> <ng-container *ngFor="let profile of profiles">
<ion-item no-padding *ngIf="profile.messages?.length > 0"> <ion-item no-padding *ngIf="profile.messages?.length > 0">
<ion-thumbnail padding-left item-start (tap)="profilePictureTapped($event, profile)"> <ion-thumbnail
<img [src]="'https://appsby.fitz.guru/urge/' + profile.details.pic.thumb"> padding-left
item-start
(tap)="profilePictureTapped($event, profile)"
>
<img [src]="'/assets/' + profile.details.pic.thumb" />
</ion-thumbnail> </ion-thumbnail>
<ion-grid (tap)="interviewTapped($event, profile)"> <ion-grid (tap)="interviewTapped($event, profile)">
<ion-row nowrap justify-content-between> <ion-row nowrap justify-content-between>
<ion-col class="username"> <ion-col class="username"> {{profile.details.name}} </ion-col>
{{profile.details.name}} <ion-col
</ion-col> class="timestamp"
<ion-col class="timestamp" [innerHTML]="getLatestMessageTimestamp(profile.messages)"></ion-col> [innerHTML]="getLatestMessageTimestamp(profile.messages)"
></ion-col>
</ion-row> </ion-row>
<ion-row class="latest-message" nowrap> <ion-row class="latest-message" nowrap>
<ion-col [innerHTML]="getLatestMessage(profile.messages)"></ion-col> <ion-col [innerHTML]="getLatestMessage(profile.messages)"></ion-col>

View File

@@ -1,30 +1,33 @@
import { Component } from '@angular/core'; import { Component } from "@angular/core";
import { DomSanitizer } from '@angular/platform-browser'; import { DomSanitizer } from "@angular/platform-browser";
import { NavController, NavParams } from 'ionic-angular'; import { NavController, NavParams } from "ionic-angular";
import { ChatPage } from '../chat/chat'; import { ChatPage } from "../chat/chat";
import { LightboxPage } from '../lightbox/lightbox'; import { LightboxPage } from "../lightbox/lightbox";
import { ProfileService } from '../../services/profiles'; import { ProfileService } from "../../services/profiles";
@Component({ @Component({
selector: 'page-profile', selector: "page-profile",
templateUrl: 'profile.html', templateUrl: "profile.html",
providers: [ ProfileService ] providers: [ProfileService],
}) })
export class ProfilePage { export class ProfilePage {
detailsOpen: boolean = false; detailsOpen: boolean = false;
profile: any; profile: any;
tabNavEl: any; tabNavEl: any;
constructor(public navCtrl: NavController, public navParams: NavParams, public profileService: ProfileService, private _sanitizer: DomSanitizer) { constructor(
this.profile = navParams.get('profile'); public navCtrl: NavController,
this.tabNavEl = document.querySelector('#tab-nav .tabbar'); public navParams: NavParams,
public profileService: ProfileService,
private _sanitizer: DomSanitizer
) {
this.profile = navParams.get("profile");
this.tabNavEl = document.querySelector("#tab-nav .tabbar");
} }
ionViewWillEnter() { ionViewWillEnter() {
this.tabNavEl.style.display = 'none'; this.tabNavEl.style.display = "none";
} }
closeProfile(event) { closeProfile(event) {
@@ -34,17 +37,19 @@ export class ProfilePage {
closeProfileDetails(event) { closeProfileDetails(event) {
if (this.detailsOpen) { if (this.detailsOpen) {
this.detailsOpen = false; this.detailsOpen = false;
document.querySelector('.profile-toolbar').classList.remove('hidden'); document.querySelector(".profile-toolbar").classList.remove("hidden");
document.getElementById('detail-overlay').classList.remove('open'); document.getElementById("detail-overlay").classList.remove("open");
} }
} }
getBackground(pics) { getBackground(pics) {
return this._sanitizer.bypassSecurityTrustStyle('url(https://appsby.fitz.guru/urge/' + pics.detail + ')'); return this._sanitizer.bypassSecurityTrustStyle(
"url(/assets/" + pics.detail + ")"
);
} }
markFavorite(event, profile) { markFavorite(event, profile) {
console.debug('favorite profile', { event: event, profile: profile }); console.debug("favorite profile", { event: event, profile: profile });
} }
nextProfile(event) { nextProfile(event) {
@@ -54,15 +59,15 @@ export class ProfilePage {
openChat(event, profile) { openChat(event, profile) {
this.navCtrl.push(ChatPage, { this.navCtrl.push(ChatPage, {
profile: profile profile: profile,
}); });
} }
openProfileDetails(event) { openProfileDetails(event) {
if (!this.detailsOpen) { if (!this.detailsOpen) {
this.detailsOpen = true; this.detailsOpen = true;
document.querySelector('.profile-toolbar').classList.add('hidden'); document.querySelector(".profile-toolbar").classList.add("hidden");
document.getElementById('detail-overlay').classList.add('open'); document.getElementById("detail-overlay").classList.add("open");
} }
} }
@@ -72,9 +77,9 @@ export class ProfilePage {
} }
showLightbox(event, image) { showLightbox(event, image) {
if (event.target.classList.contains('scroll-content')) { if (event.target.classList.contains("scroll-content")) {
this.navCtrl.push(LightboxPage, { this.navCtrl.push(LightboxPage, {
image: image image: image,
}); });
} }
} }

View File

@@ -1,20 +1,18 @@
import { Injectable } from '@angular/core'; import { Injectable } from "@angular/core";
import { Http } from '@angular/http'; import { Http } from "@angular/http";
import 'rxjs/add/operator/map'; import "rxjs/add/operator/map";
@Injectable() @Injectable()
export class ProfileService { export class ProfileService {
endpoint: string = "http://localhost:27017/urnings/profiles";
endpoint: string = 'https://api.fitz.guru/urnings/profiles'; fallback: string = "assets/data/profiles.json";
fallback: string = 'assets/data/profiles.json'; epSubmitted: string = "/submitted";
epSubmitted: string = '/submitted'; epVerified: string = "/verified";
epVerified: string = '/verified';
idMap: any = { all: {}, submitted: {}, verified: {} }; idMap: any = { all: {}, submitted: {}, verified: {} };
profiles: any; profiles: any;
constructor(private http: Http) { constructor(private http: Http) {
this.idMap = {}; this.idMap = { all: {}, submitted: {}, verified: {} };
this.profiles = null; this.profiles = null;
} }
@@ -23,7 +21,7 @@ export class ProfileService {
return Promise.resolve(this.profiles); return Promise.resolve(this.profiles);
} }
return new Promise(resolve => { return new Promise((resolve) => {
this.doGetRequest(this.endpoint, resolve); this.doGetRequest(this.endpoint, resolve);
}); });
} }
@@ -33,8 +31,8 @@ export class ProfileService {
return Promise.resolve(this.profiles.submitted); return Promise.resolve(this.profiles.submitted);
} }
return new Promise(resolve => { return new Promise((resolve) => {
this.doGetRequest(this.endpoint + this.epSubmitted, resolve, 'submitted'); this.doGetRequest(this.endpoint + this.epSubmitted, resolve, "submitted");
}); });
} }
@@ -43,39 +41,42 @@ export class ProfileService {
return Promise.resolve(this.profiles.verified); return Promise.resolve(this.profiles.verified);
} }
return new Promise(resolve => { return new Promise((resolve) => {
this.doGetRequest(this.endpoint + this.epVerified, resolve, 'verified'); this.doGetRequest(this.endpoint + this.epVerified, resolve, "verified");
}); });
} }
doGetRequest(endpoint, resolve, type = 'all') { doGetRequest(endpoint, resolve, type = "all") {
this.http.get(endpoint) this.http
.map(res => res.json()) .get(endpoint)
.map((res) => res.json())
.subscribe( .subscribe(
data => { (data) => {
this.profiles = this.profiles || {}; this.profiles = this.profiles || {};
this.profiles[type] = data; this.profiles[type] = data;
this.profiles[type].reduce((map, profile, i) => { this.profiles[type].reduce((map, profile, i) => {
console.log("profile: ", { map, profile, i });
map[profile._id] = i; map[profile._id] = i;
return map; return map;
}, this.idMap[type]); }, this.idMap[type]);
resolve(this.profiles[type]); resolve(this.profiles[type]);
}, },
error => { (error) => {
this.doGetRequest(this.fallback, resolve, type); this.doGetRequest(this.fallback, resolve, type);
} }
) );
} }
getNextProfile(id, type = 'all') { getNextProfile(id, type = "all") {
var nextIdIndex = this.idMap[type][id] + 1; var nextIdIndex = this.idMap[type][id] + 1;
nextIdIndex = nextIdIndex >= this.profiles[type].length ? 0 : nextIdIndex; nextIdIndex = nextIdIndex >= this.profiles[type].length ? 0 : nextIdIndex;
return this.profiles[type][nextIdIndex]; return this.profiles[type][nextIdIndex];
} }
getPreviousProfile(id, type = 'all') { getPreviousProfile(id, type = "all") {
var prevIdIndex = this.idMap[type][id] - 1; var prevIdIndex = this.idMap[type][id] - 1;
prevIdIndex = prevIdIndex < 0 ? (this.profiles[type].length - 1) : prevIdIndex; prevIdIndex =
prevIdIndex < 0 ? this.profiles[type].length - 1 : prevIdIndex;
return this.profiles[type][prevIdIndex]; return this.profiles[type][prevIdIndex];
} }

View File

@@ -1,101 +0,0 @@
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('urge-api:server');
var http = require('http');
var mongoose = require('mongoose');
/**
* Connect to the Mongo DB
*/
mongoose.connect('mongodb://localhost:27017/urge', (err) => {
if(err) {
throw new Error(err);
} else {
}
});
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3069');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}

File diff suppressed because one or more lines are too long

View File

@@ -1,21 +0,0 @@
version: '3.8'
services:
backend:
build: .
ports:
- "3069:3069"
depends_on:
- mongo
environment:
- MONGODB_URI=mongodb://mongo:27017/urge
mongo:
image: mongo:4.4
ports:
- "27017:27017"
volumes:
- mongo-data:/data/db
volumes:
mongo-data:

2542
backend/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
"version": "0.2.1", "version": "0.2.1",
"private": true, "private": true,
"scripts": { "scripts": {
"start": "node ./bin/www" "start": "node ./src/bin/www"
}, },
"dependencies": { "dependencies": {
"@google/maps": "^0.4.5", "@google/maps": "^0.4.5",
@@ -39,12 +39,6 @@
"type": "git", "type": "git",
"url": "git@git.mifi.dev:12022/mifi/Pfosi-Looking-API.git" "url": "git@git.mifi.dev:12022/mifi/Pfosi-Looking-API.git"
}, },
"keywords": [
"Timberland",
"TBL",
"GCS",
"database"
],
"author": "Mike Fitzpatrick (badmf@mifi.dev)", "author": "Mike Fitzpatrick (badmf@mifi.dev)",
"license": "ISC" "license": "ISC"
} }

107
backend/src/bin/www Executable file
View File

@@ -0,0 +1,107 @@
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require("../app");
var debug = require("debug")("urge-api:server");
var http = require("http");
var mongoose = require("mongoose");
/**
* Connect to the Mongo DB
*/
// Use mongo service name for Docker container
const mongoUrl = process.env.MONGODB_URL || "mongodb://mongo:27017/urge";
mongoose
.connect(mongoUrl, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
console.log("Connected to MongoDB successfully");
})
.catch((err) => {
console.error("MongoDB connection error:", err.message);
console.error("Please ensure MongoDB is running on", mongoUrl);
process.exit(1);
});
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || "3069");
app.set("port", port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on("error", onError);
server.on("listening", onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== "listen") {
throw error;
}
var bind = typeof port === "string" ? "Pipe " + port : "Port " + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case "EACCES":
console.error(bind + " requires elevated privileges");
process.exit(1);
break;
case "EADDRINUSE":
console.error(bind + " is already in use");
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port;
debug("Listening on " + bind);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 616 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 816 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Some files were not shown because too many files have changed in this diff Show More