Implement Country search
This commit is contained in:
parent
881bb1baf1
commit
5f80b1d912
8 changed files with 124 additions and 7 deletions
|
@ -12,6 +12,7 @@ const pricemodel = require('./models/price');
|
||||||
const txmodel = require('./models/tx');
|
const txmodel = require('./models/tx');
|
||||||
const paymentmodel = require('./models/payment');
|
const paymentmodel = require('./models/payment');
|
||||||
const zecTxModel = require('./models/zectxs.js');
|
const zecTxModel = require('./models/zectxs.js');
|
||||||
|
const countryModel = require('./models/country.js');
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const stdrpc = require('stdrpc');
|
const stdrpc = require('stdrpc');
|
||||||
const CoinGecko = require('coingecko-api');
|
const CoinGecko = require('coingecko-api');
|
||||||
|
@ -225,6 +226,22 @@ app.get('/api/test', (req, res, next) => {
|
||||||
res.status(200).send('Endpoint triggered');
|
res.status(200).send('Endpoint triggered');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.get('/api/countries', (req, res, next) => {
|
||||||
|
console.log('Get: /api/countries');
|
||||||
|
countryModel.find({}).then((documents) => {
|
||||||
|
if (documents != null) {
|
||||||
|
res.status(200).json({
|
||||||
|
message: 'Country data found',
|
||||||
|
countries: documents
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
res.status(204).json({
|
||||||
|
message: 'No country data available'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
app.get('/api/users', (req, res, next) => {
|
app.get('/api/users', (req, res, next) => {
|
||||||
console.log('Get: /api/users');
|
console.log('Get: /api/users');
|
||||||
usermodel.find({'address': req.query.address, 'session': req.query.session}).
|
usermodel.find({'address': req.query.address, 'session': req.query.session}).
|
||||||
|
|
9
backend/models/country.js
Normal file
9
backend/models/country.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
const countrySchema = mongoose.Schema({
|
||||||
|
name: {type: String, required: true},
|
||||||
|
code: {type: Number, required: true}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = mongoose.model('Country', countrySchema);
|
|
@ -2,6 +2,7 @@ import { NgModule } from '@angular/core';
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
import { MatInputModule } from '@angular/material/input';
|
||||||
|
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||||
import { MatCardModule } from '@angular/material/card';
|
import { MatCardModule } from '@angular/material/card';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||||
|
@ -32,6 +33,7 @@ import { ListOrdersComponent } from './listorders/listorders.component';
|
||||||
import { ScanComponent } from './scan/scan.component';
|
import { ScanComponent } from './scan/scan.component';
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { BusinessComponent } from './business/business.component';
|
import { BusinessComponent } from './business/business.component';
|
||||||
|
import { SearchOptionsPipe } from './searchoptions.pipe';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
|
@ -49,7 +51,8 @@ import { BusinessComponent } from './business/business.component';
|
||||||
SettingsComponent,
|
SettingsComponent,
|
||||||
ScanComponent,
|
ScanComponent,
|
||||||
ListOrdersComponent,
|
ListOrdersComponent,
|
||||||
BusinessComponent
|
BusinessComponent,
|
||||||
|
SearchOptionsPipe
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
@ -69,6 +72,7 @@ import { BusinessComponent } from './business/business.component';
|
||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
MatProgressBarModule,
|
MatProgressBarModule,
|
||||||
MatStepperModule,
|
MatStepperModule,
|
||||||
|
MatAutocompleteModule,
|
||||||
BrowserAnimationsModule
|
BrowserAnimationsModule
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
|
|
|
@ -1,11 +1,43 @@
|
||||||
<app-header></app-header>
|
<app-header></app-header>
|
||||||
<p>business works!</p>
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<mat-card class="centercard" [formGroup]="bizForm">
|
<mat-card class="centercard" [formGroup]="bizForm">
|
||||||
<p>Form</p>
|
<p>Business Information</p>
|
||||||
<mat-form-field appearance="outline">
|
<mat-form-field appearance="outline">
|
||||||
<mat-label>Business Name</mat-label>
|
<mat-label>Business Name</mat-label>
|
||||||
<input matInput placeholder="Business Name" formControlName="name">
|
<input matInput placeholder="Business Name" formControlName="name">
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>Address</mat-label>
|
||||||
|
<input matInput placeholder="Address" formControlName="street">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>City</mat-label>
|
||||||
|
<input matInput placeholder="City" formControlName="city">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>State/Province</mat-label>
|
||||||
|
<input matInput placeholder="State or Province" formControlName="state">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>Postal Code</mat-label>
|
||||||
|
<input matInput placeholder="Postal Code" formControlName="postal">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>Country</mat-label>
|
||||||
|
<input matInput placeholder="Country" formControlName="country" [matAutocomplete]="auto">
|
||||||
|
<mat-autocomplete #auto="matAutocomplete">
|
||||||
|
<mat-option *ngFor="let ctry of countries | searchOptions:bizForm.get('country')!.value" [value]="ctry.name">
|
||||||
|
{{ctry.name}}
|
||||||
|
</mat-option>
|
||||||
|
</mat-autocomplete>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>E-mail</mat-label>
|
||||||
|
<input matInput placeholder="E-mail" formControlName="email">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>Website</mat-label>
|
||||||
|
<input matInput placeholder="Website" formControlName="website">
|
||||||
|
</mat-form-field>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { FormBuilder, Validators, FormGroup, FormControl } from '@angular/forms';
|
import { FormBuilder, Validators, FormGroup, FormControl } from '@angular/forms';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { filter, startWith, map, switchMap } from 'rxjs/operators';
|
||||||
|
import { Country } from '../country.model';
|
||||||
import { Owner } from '../owner.model';
|
import { Owner } from '../owner.model';
|
||||||
import { UserService } from '../user.service';
|
import { UserService } from '../user.service';
|
||||||
|
import { SearchOptionsPipe } from '../searchoptions.pipe';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-business',
|
selector: 'app-business',
|
||||||
|
@ -11,12 +15,28 @@ import { UserService } from '../user.service';
|
||||||
export class BusinessComponent implements OnInit {
|
export class BusinessComponent implements OnInit {
|
||||||
|
|
||||||
bizForm: FormGroup;
|
bizForm: FormGroup;
|
||||||
|
countries: Country[] = [];
|
||||||
|
public countriesUpdate: Observable<Country[]>;
|
||||||
|
testSearch = 'uni';
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private fb: FormBuilder
|
private fb: FormBuilder,
|
||||||
|
private userService: UserService
|
||||||
) {
|
) {
|
||||||
|
this.countriesUpdate = userService.countriesUpdate;
|
||||||
this.bizForm = fb.group({
|
this.bizForm = fb.group({
|
||||||
name: ['', Validators.required]
|
name: ['', Validators.required],
|
||||||
|
street: ['', Validators.required],
|
||||||
|
city: ['', Validators.required],
|
||||||
|
state: ['', Validators.required],
|
||||||
|
postal: ['', Validators.required],
|
||||||
|
country: ['', Validators.required],
|
||||||
|
email: ['', Validators.required],
|
||||||
|
website: ['', Validators.required]
|
||||||
|
});
|
||||||
|
this.userService.getCountries();
|
||||||
|
this.countriesUpdate.subscribe((countries) => {
|
||||||
|
this.countries = countries;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
src/app/country.model.ts
Normal file
5
src/app/country.model.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
export interface Country {
|
||||||
|
_id?: string;
|
||||||
|
name: string;
|
||||||
|
code: string;
|
||||||
|
}
|
15
src/app/searchoptions.pipe.ts
Normal file
15
src/app/searchoptions.pipe.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'searchOptions'
|
||||||
|
})
|
||||||
|
export class SearchOptionsPipe implements PipeTransform {
|
||||||
|
transform(items: any[], filter: string): any {
|
||||||
|
if (!items || !filter) {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will search and match any option.value that contains the search term
|
||||||
|
return items.filter(item => item.name.toLowerCase().indexOf(filter.toLowerCase()) !== -1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,13 +3,14 @@ import {Subject, BehaviorSubject, Observable} from 'rxjs';
|
||||||
import {HttpClient, HttpParams, HttpHeaders} from '@angular/common/http';
|
import {HttpClient, HttpParams, HttpHeaders} from '@angular/common/http';
|
||||||
import {User} from './user.model';
|
import {User} from './user.model';
|
||||||
import {Owner} from './owner.model';
|
import {Owner} from './owner.model';
|
||||||
|
import { Country } from './country.model';
|
||||||
import {Tx} from './tx.model';
|
import {Tx} from './tx.model';
|
||||||
|
|
||||||
@Injectable({providedIn: 'root'})
|
@Injectable({providedIn: 'root'})
|
||||||
|
|
||||||
export class UserService{
|
export class UserService{
|
||||||
beUrl = 'http://localhost:3000/';
|
beUrl = 'http://localhost:3000/';
|
||||||
private dataStore: { user: User, owner: Owner, txs: Tx[]} = {
|
private dataStore: { user: User, owner: Owner, txs: Tx[], countries: Country[]} = {
|
||||||
user: {
|
user: {
|
||||||
address: '',
|
address: '',
|
||||||
session: '',
|
session: '',
|
||||||
|
@ -36,7 +37,8 @@ export class UserService{
|
||||||
website: '',
|
website: '',
|
||||||
country: ''
|
country: ''
|
||||||
},
|
},
|
||||||
txs : []
|
txs : [],
|
||||||
|
countries: []
|
||||||
};
|
};
|
||||||
private uZaddr = '';
|
private uZaddr = '';
|
||||||
private oZaddr = '';
|
private oZaddr = '';
|
||||||
|
@ -48,11 +50,13 @@ export class UserService{
|
||||||
private _ownerUpdated: BehaviorSubject<Owner> = new BehaviorSubject(this.dataStore.owner);
|
private _ownerUpdated: BehaviorSubject<Owner> = new BehaviorSubject(this.dataStore.owner);
|
||||||
private _txsUpdated: BehaviorSubject<Tx[]> = new BehaviorSubject(this.dataStore.txs);
|
private _txsUpdated: BehaviorSubject<Tx[]> = new BehaviorSubject(this.dataStore.txs);
|
||||||
private _paidUpdated: BehaviorSubject<boolean> = new BehaviorSubject(this.dataStore.owner.paid);
|
private _paidUpdated: BehaviorSubject<boolean> = new BehaviorSubject(this.dataStore.owner.paid);
|
||||||
|
private _countriesUpdated: BehaviorSubject<Country[]> = new BehaviorSubject(this.dataStore.countries);
|
||||||
public readonly uZaddrUpdate: Observable<string> = this._uZaddrUpdated.asObservable();
|
public readonly uZaddrUpdate: Observable<string> = this._uZaddrUpdated.asObservable();
|
||||||
public readonly ownerUpdate: Observable<Owner> = this._ownerUpdated.asObservable();
|
public readonly ownerUpdate: Observable<Owner> = this._ownerUpdated.asObservable();
|
||||||
public readonly userUpdate: Observable<User> = this._userUpdated.asObservable();
|
public readonly userUpdate: Observable<User> = this._userUpdated.asObservable();
|
||||||
public readonly txUpdate: Observable<Tx[]> = this._txsUpdated.asObservable();
|
public readonly txUpdate: Observable<Tx[]> = this._txsUpdated.asObservable();
|
||||||
public readonly paidUpdate: Observable<boolean> = this._paidUpdated.asObservable();
|
public readonly paidUpdate: Observable<boolean> = this._paidUpdated.asObservable();
|
||||||
|
public readonly countriesUpdate: Observable<Country[]> = this._countriesUpdated.asObservable();
|
||||||
private reqHeaders: HttpHeaders;
|
private reqHeaders: HttpHeaders;
|
||||||
private apiKey = 'Le2adeic8Thah4Aeng4daem6i';
|
private apiKey = 'Le2adeic8Thah4Aeng4daem6i';
|
||||||
|
|
||||||
|
@ -66,6 +70,17 @@ export class UserService{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCountries() {
|
||||||
|
let obs = this.http.get<{message: string, countries: any}>(this.beUrl+'api/countries', { headers: this.reqHeaders, observe: 'response'});
|
||||||
|
|
||||||
|
obs.subscribe((CountryResponse) => {
|
||||||
|
if (CountryResponse.status == 200) {
|
||||||
|
this.dataStore.countries = CountryResponse.body!.countries;
|
||||||
|
this._countriesUpdated.next(Object.assign({}, this.dataStore).countries);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
findUser() {
|
findUser() {
|
||||||
this.session = localStorage.getItem('s4z_token');
|
this.session = localStorage.getItem('s4z_token');
|
||||||
if (this.session != null) {
|
if (this.session != null) {
|
||||||
|
|
Loading…
Reference in a new issue