From e73fc2c2b21b617c11df2dfeb03c96e4152c74ac Mon Sep 17 00:00:00 2001
From: Piotr K <44520613+astropio3000@users.noreply.github.com>
Date: Sat, 27 May 2023 06:45:51 +0200
Subject: [PATCH] frontttt
---
.../src/issues/dto/create-issue.dto.ts | 2 +-
apps/frontend/angular.json | 6 ++
apps/frontend/src/app/app-routing.module.ts | 7 +++
apps/frontend/src/app/app.component.html | 12 ++++
.../frontend/src/app/models/solution.model.ts | 1 +
.../app/modules/report/report.component.html | 2 +-
.../app/modules/report/report.component.ts | 21 ++++++-
.../modules/report/services/report.service.ts | 46 ++++++++++++++-
.../services/solution-form.service.ts | 21 +++++++
.../solution-form-routiong.module.ts | 11 ++++
.../solution-form.component.html | 32 +++++++++++
.../solution-form.component.scss | 11 ++++
.../solution-form/solution-form.component.ts | 57 +++++++++++++++++++
.../solution-form/solution-form.module.ts | 27 +++++++++
.../src/app/services/solutions.service.ts | 30 +++++-----
.../src/app/store/actions/issue.actions.ts | 4 ++
.../src/app/store/actions/solution.actions.ts | 11 ++++
.../src/app/store/effect/issue.effect.ts | 2 +-
.../src/app/store/effect/solution.effect.ts | 32 +++++++++++
.../src/app/store/reducer/issue.reducer.ts | 26 ++++++++-
.../src/environments/environments.prod.ts | 3 +
.../frontend/src/environments/environments.ts | 4 ++
22 files changed, 344 insertions(+), 24 deletions(-)
create mode 100644 apps/frontend/src/app/modules/solution-form/services/solution-form.service.ts
create mode 100644 apps/frontend/src/app/modules/solution-form/solution-form-routiong.module.ts
create mode 100644 apps/frontend/src/app/modules/solution-form/solution-form.component.html
create mode 100644 apps/frontend/src/app/modules/solution-form/solution-form.component.scss
create mode 100644 apps/frontend/src/app/modules/solution-form/solution-form.component.ts
create mode 100644 apps/frontend/src/app/modules/solution-form/solution-form.module.ts
create mode 100644 apps/frontend/src/app/store/actions/solution.actions.ts
create mode 100644 apps/frontend/src/app/store/effect/solution.effect.ts
create mode 100644 apps/frontend/src/environments/environments.prod.ts
create mode 100644 apps/frontend/src/environments/environments.ts
diff --git a/apps/backend/src/issues/dto/create-issue.dto.ts b/apps/backend/src/issues/dto/create-issue.dto.ts
index 09fff86..3d5b076 100644
--- a/apps/backend/src/issues/dto/create-issue.dto.ts
+++ b/apps/backend/src/issues/dto/create-issue.dto.ts
@@ -32,5 +32,5 @@ export class CreateIssueDto {
latitude: number;
@IsNumber()
- longitude: string;
+ longitude: number;
}
diff --git a/apps/frontend/angular.json b/apps/frontend/angular.json
index 308f72b..895327a 100644
--- a/apps/frontend/angular.json
+++ b/apps/frontend/angular.json
@@ -33,6 +33,12 @@
},
"configurations": {
"production": {
+ "fileReplacements": [
+ {
+ "replace": "src/environments/environments.ts",
+ "with": "src/environments/environments.prod.ts"
+ }
+ ],
"budgets": [
{
"type": "initial",
diff --git a/apps/frontend/src/app/app-routing.module.ts b/apps/frontend/src/app/app-routing.module.ts
index 8238442..b7071be 100644
--- a/apps/frontend/src/app/app-routing.module.ts
+++ b/apps/frontend/src/app/app-routing.module.ts
@@ -24,6 +24,13 @@ const routes: Routes = [
loadChildren: () =>
import('./modules/report/report.module').then((m) => m.ReportModule),
},
+ {
+ path: 'solution-form',
+ loadChildren: () =>
+ import('./modules/solution-form/solution-form.module').then(
+ (m) => m.SolutionFormModule
+ ),
+ },
];
@NgModule({
diff --git a/apps/frontend/src/app/app.component.html b/apps/frontend/src/app/app.component.html
index 6099999..891d9ec 100644
--- a/apps/frontend/src/app/app.component.html
+++ b/apps/frontend/src/app/app.component.html
@@ -31,5 +31,17 @@
label="Rozwiązania"
[routerLink]="['/', 'solutions']"
>
+
+
diff --git a/apps/frontend/src/app/models/solution.model.ts b/apps/frontend/src/app/models/solution.model.ts
index cbcaa69..304cd2c 100644
--- a/apps/frontend/src/app/models/solution.model.ts
+++ b/apps/frontend/src/app/models/solution.model.ts
@@ -1,6 +1,7 @@
import { CommentModel } from './comment.model';
export interface SolutionModel {
+ id?: string;
title: string;
description: string;
comments: CommentModel[];
diff --git a/apps/frontend/src/app/modules/report/report.component.html b/apps/frontend/src/app/modules/report/report.component.html
index ca7ebc9..c46b303 100644
--- a/apps/frontend/src/app/modules/report/report.component.html
+++ b/apps/frontend/src/app/modules/report/report.component.html
@@ -39,7 +39,7 @@
-
+
diff --git a/apps/frontend/src/app/modules/report/report.component.ts b/apps/frontend/src/app/modules/report/report.component.ts
index 8fe75ea..ff6cae5 100644
--- a/apps/frontend/src/app/modules/report/report.component.ts
+++ b/apps/frontend/src/app/modules/report/report.component.ts
@@ -1,5 +1,6 @@
import { Component } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
+import { ReportService } from './services/report.service';
@Component({
selector: 'app-report',
@@ -7,9 +8,13 @@ import { FormControl, FormGroup, Validators } from '@angular/forms';
styleUrls: ['./report.component.scss'],
})
export class ReportComponent {
+ constructor(private reportService: ReportService) {}
formGroup = new FormGroup({
userName: new FormControl('', Validators.required),
- cords: new FormControl(undefined, Validators.required),
+ cords: new FormControl(
+ undefined as unknown as [number, number],
+ Validators.required
+ ),
title: new FormControl('', Validators.required),
type: new FormControl(undefined, Validators.required),
description: new FormControl('', Validators.required),
@@ -19,4 +24,18 @@ export class ReportComponent {
{ value: 'problem', label: 'Problem' },
{ value: 'suggestion', label: 'Sugestia' },
];
+ submit() {
+ const form = this.formGroup.getRawValue();
+ if (form.cords)
+ this.reportService
+ .createIssue(
+ form.title || '',
+ form.userName || '',
+ form.description || '',
+ form.type || '',
+ form.cords[0] || 0,
+ form.cords[1] || 0
+ )
+ .subscribe(console.log);
+ }
}
diff --git a/apps/frontend/src/app/modules/report/services/report.service.ts b/apps/frontend/src/app/modules/report/services/report.service.ts
index 924f80d..fcc8267 100644
--- a/apps/frontend/src/app/modules/report/services/report.service.ts
+++ b/apps/frontend/src/app/modules/report/services/report.service.ts
@@ -1,6 +1,50 @@
+import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
+import { Store } from '@ngrx/store';
+import { tap } from 'rxjs';
+import { addIssueAction } from 'src/app/store/actions/issue.actions';
+import { environments } from 'src/environments/environments';
@Injectable({
providedIn: 'root',
})
-export class ReportService {}
+export class ReportService {
+ constructor(private http: HttpClient, private store: Store) {}
+ createIssue(
+ title: string,
+ username: string,
+ desc: string,
+ type: string,
+ latitude: number,
+ longitude: number
+ ) {
+ return this.http
+ .post(environments.apiUrl + '/issues', {
+ title,
+ username,
+ description: desc,
+ type,
+ longitude,
+ latitude,
+ })
+ .pipe(
+ tap((res: any) => {
+ this.store.dispatch(
+ addIssueAction({
+ issue: {
+ comments: [],
+ cords: [longitude, latitude],
+ createdAt: new Date(),
+ description: desc,
+ id: res.id,
+ photos: [],
+ status: 'new',
+ title,
+ type: type as 'problem' | 'suggestion',
+ },
+ })
+ );
+ })
+ );
+ }
+}
diff --git a/apps/frontend/src/app/modules/solution-form/services/solution-form.service.ts b/apps/frontend/src/app/modules/solution-form/services/solution-form.service.ts
new file mode 100644
index 0000000..29e0c0e
--- /dev/null
+++ b/apps/frontend/src/app/modules/solution-form/services/solution-form.service.ts
@@ -0,0 +1,21 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { Store } from '@ngrx/store';
+import { tap } from 'rxjs';
+import { IssueModel } from 'src/app/models/issue.model';
+import { environments } from 'src/environments/environments';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class SolutionFormService {
+ constructor(private http: HttpClient, private store: Store) {}
+ createSolution(issue: IssueModel, title: string, description: string) {
+ return this.http
+ .post(environments.apiUrl + '/issues/' + issue.id + '/solution', {
+ title,
+ description,
+ })
+ .pipe(tap());
+ }
+}
diff --git a/apps/frontend/src/app/modules/solution-form/solution-form-routiong.module.ts b/apps/frontend/src/app/modules/solution-form/solution-form-routiong.module.ts
new file mode 100644
index 0000000..66dfaea
--- /dev/null
+++ b/apps/frontend/src/app/modules/solution-form/solution-form-routiong.module.ts
@@ -0,0 +1,11 @@
+import { NgModule } from '@angular/core';
+import { RouterModule, Routes } from '@angular/router';
+import { SolutionFormComponent } from './solution-form.component';
+
+const routes: Routes = [{ path: '', component: SolutionFormComponent }];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule],
+})
+export class SolutionFormRoutingModule {}
diff --git a/apps/frontend/src/app/modules/solution-form/solution-form.component.html b/apps/frontend/src/app/modules/solution-form/solution-form.component.html
new file mode 100644
index 0000000..7ff73e7
--- /dev/null
+++ b/apps/frontend/src/app/modules/solution-form/solution-form.component.html
@@ -0,0 +1,32 @@
+
diff --git a/apps/frontend/src/app/modules/solution-form/solution-form.component.scss b/apps/frontend/src/app/modules/solution-form/solution-form.component.scss
new file mode 100644
index 0000000..9c23e58
--- /dev/null
+++ b/apps/frontend/src/app/modules/solution-form/solution-form.component.scss
@@ -0,0 +1,11 @@
+.report {
+ max-width: 900px;
+ margin: auto;
+}
+
+form {
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ gap: 30px;
+}
diff --git a/apps/frontend/src/app/modules/solution-form/solution-form.component.ts b/apps/frontend/src/app/modules/solution-form/solution-form.component.ts
new file mode 100644
index 0000000..700a2fd
--- /dev/null
+++ b/apps/frontend/src/app/modules/solution-form/solution-form.component.ts
@@ -0,0 +1,57 @@
+import { Component, OnInit } from '@angular/core';
+import { FormControl, FormGroup, Validators } from '@angular/forms';
+import { Store } from '@ngrx/store';
+import { EMPTY, Observable, map, tap } from 'rxjs';
+import { IssueModel } from 'src/app/models/issue.model';
+import { receiveAllIssuesAction } from 'src/app/store/actions/issue.actions';
+import { selectAllIssues } from 'src/app/store/selectors/issue.selectors';
+import { SolutionFormService } from './services/solution-form.service';
+
+@Component({
+ selector: 'app-solution-form',
+ templateUrl: './solution-form.component.html',
+ styleUrls: ['./solution-form.component.scss'],
+})
+export class SolutionFormComponent implements OnInit {
+ issues$: Observable = EMPTY;
+
+ issuesOptions$: Observable = EMPTY;
+
+ constructor(
+ private solutionFormService: SolutionFormService,
+ private store: Store
+ ) {}
+
+ formGroup = new FormGroup({
+ issue: new FormControl(
+ undefined as unknown as IssueModel,
+ Validators.required
+ ),
+ title: new FormControl('', Validators.required),
+ description: new FormControl('', Validators.required),
+ });
+
+ ngOnInit(): void {
+ this.store.dispatch(receiveAllIssuesAction());
+ this.issues$ = this.store.select(selectAllIssues);
+ this.issuesOptions$ = this.issues$.pipe(
+ map((issues) =>
+ issues.map((issue) => ({
+ label: issue.title,
+ value: issue,
+ }))
+ ),
+ tap(console.log)
+ );
+ }
+ submit() {
+ const form = this.formGroup.getRawValue();
+ this.solutionFormService
+ .createSolution(
+ form.issue as IssueModel,
+ form.title || '',
+ form.description || ''
+ )
+ .subscribe(console.log);
+ }
+}
diff --git a/apps/frontend/src/app/modules/solution-form/solution-form.module.ts b/apps/frontend/src/app/modules/solution-form/solution-form.module.ts
new file mode 100644
index 0000000..6d9e991
--- /dev/null
+++ b/apps/frontend/src/app/modules/solution-form/solution-form.module.ts
@@ -0,0 +1,27 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { ReactiveFormsModule } from '@angular/forms';
+import { ButtonModule } from 'primeng/button';
+import { CardModule } from 'primeng/card';
+import { DropdownModule } from 'primeng/dropdown';
+import { InputTextModule } from 'primeng/inputtext';
+import { InputTextareaModule } from 'primeng/inputtextarea';
+import { ListboxModule } from 'primeng/listbox';
+import { SolutionFormRoutingModule } from './solution-form-routiong.module';
+import { SolutionFormComponent } from './solution-form.component';
+@NgModule({
+ declarations: [SolutionFormComponent],
+ imports: [
+ CommonModule,
+ CardModule,
+ InputTextModule,
+ ReactiveFormsModule,
+ SolutionFormRoutingModule,
+ ListboxModule,
+ InputTextareaModule,
+ ButtonModule,
+ DropdownModule,
+ ],
+ providers: [],
+})
+export class SolutionFormModule {}
diff --git a/apps/frontend/src/app/services/solutions.service.ts b/apps/frontend/src/app/services/solutions.service.ts
index 1af2224..f4cfab0 100644
--- a/apps/frontend/src/app/services/solutions.service.ts
+++ b/apps/frontend/src/app/services/solutions.service.ts
@@ -1,32 +1,30 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { map } from 'rxjs';
-import { SolutionModel } from '../models/solution.model';
import { CommentModel } from '../models/comment.model';
+import { SolutionModel } from '../models/solution.model';
@Injectable({
providedIn: 'root',
})
-export class IssueService {
+export class SolutionService {
constructor(private http: HttpClient) {}
- getSolutions(id: string) {
- return this.http.get('/issue/'+id+'/solution').pipe(
- map((solution) =>
- solution.map((solution) => ({
- title: solution.title,
- description: solution.description,
- comments: solution.comments,
- createdAt: solution.createdAt
- }))
- )
+ getSolution(id: string) {
+ return this.http.get('/issue/' + id + '/solution').pipe(
+ map((solution) => ({
+ title: solution.title,
+ description: solution.description,
+ comments: solution.comments,
+ createdAt: solution.createdAt,
+ }))
);
}
}
interface SolutionDto {
- title: string,
- description: string,
- comments: CommentModel[],
- createdAt: Date
+ title: string;
+ description: string;
+ comments: CommentModel[];
+ createdAt: Date;
}
diff --git a/apps/frontend/src/app/store/actions/issue.actions.ts b/apps/frontend/src/app/store/actions/issue.actions.ts
index fd488aa..3f0c001 100644
--- a/apps/frontend/src/app/store/actions/issue.actions.ts
+++ b/apps/frontend/src/app/store/actions/issue.actions.ts
@@ -11,3 +11,7 @@ export const receivedAllIssuesSuccessAction = createAction(
export const receivedAllIssuesErrorAction = createAction(
'[issues] received all issues error'
);
+export const addIssueAction = createAction(
+ '[issues] add issue',
+ props<{ issue: IssueModel }>()
+);
diff --git a/apps/frontend/src/app/store/actions/solution.actions.ts b/apps/frontend/src/app/store/actions/solution.actions.ts
new file mode 100644
index 0000000..689bd06
--- /dev/null
+++ b/apps/frontend/src/app/store/actions/solution.actions.ts
@@ -0,0 +1,11 @@
+import { createAction, props } from '@ngrx/store';
+import { SolutionModel } from 'src/app/models/solution.model';
+
+export const receiveSolutionAction = createAction(
+ '[solution] receive solution',
+ props<{ issueId: string }>()
+);
+export const receivedSolutionSuccessAction = createAction(
+ '[solution] receive solution',
+ props<{ issueId: string; solution: SolutionModel }>()
+);
diff --git a/apps/frontend/src/app/store/effect/issue.effect.ts b/apps/frontend/src/app/store/effect/issue.effect.ts
index 5030881..ba83f6d 100644
--- a/apps/frontend/src/app/store/effect/issue.effect.ts
+++ b/apps/frontend/src/app/store/effect/issue.effect.ts
@@ -10,7 +10,7 @@ import {
@Injectable({ providedIn: 'root' })
export class IssueEffect {
- preloadAutomaticOffer$ = createEffect(() => {
+ loadIssues$ = createEffect(() => {
return this.actions$.pipe(
ofType(receiveAllIssuesAction),
switchMap((action) => this.issueService.getIssues()),
diff --git a/apps/frontend/src/app/store/effect/solution.effect.ts b/apps/frontend/src/app/store/effect/solution.effect.ts
new file mode 100644
index 0000000..3960f14
--- /dev/null
+++ b/apps/frontend/src/app/store/effect/solution.effect.ts
@@ -0,0 +1,32 @@
+import { Injectable } from '@angular/core';
+import { Actions, createEffect, ofType } from '@ngrx/effects';
+import { map, switchMap } from 'rxjs';
+import { SolutionService } from 'src/app/services/solutions.service';
+import {
+ receiveSolutionAction,
+ receivedSolutionSuccessAction,
+} from '../actions/solution.actions';
+
+@Injectable({ providedIn: 'root' })
+export class SolutionEffect {
+ loadSolution$ = createEffect(() => {
+ return this.actions$.pipe(
+ ofType(receiveSolutionAction),
+ switchMap((action) =>
+ this.solutionService.getSolution(action.issueId).pipe(
+ map((solution) =>
+ receivedSolutionSuccessAction({
+ issueId: action.issueId,
+ solution,
+ })
+ )
+ )
+ )
+ );
+ });
+
+ constructor(
+ private actions$: Actions,
+ private solutionService: SolutionService
+ ) {}
+}
diff --git a/apps/frontend/src/app/store/reducer/issue.reducer.ts b/apps/frontend/src/app/store/reducer/issue.reducer.ts
index bb60a9b..1e5b59f 100644
--- a/apps/frontend/src/app/store/reducer/issue.reducer.ts
+++ b/apps/frontend/src/app/store/reducer/issue.reducer.ts
@@ -1,5 +1,9 @@
import { createReducer, on } from '@ngrx/store';
-import { receivedAllIssuesSuccessAction } from '../actions/issue.actions';
+import {
+ addIssueAction,
+ receivedAllIssuesSuccessAction,
+} from '../actions/issue.actions';
+import { receivedSolutionSuccessAction } from '../actions/solution.actions';
import { IssueState } from '../state/issue.state';
const initialState: IssueState = {
@@ -38,8 +42,8 @@ const initialState: IssueState = {
solution: {
comments: [],
createdAt: new Date(),
- description: "eoooo",
- title: "title"
+ description: 'eoooo',
+ title: 'title',
},
comments: [],
},
@@ -61,5 +65,21 @@ export const issueReducer = createReducer(
initialState,
on(receivedAllIssuesSuccessAction, (state: IssueState, action) => ({
issues: action.issues,
+ })),
+ on(addIssueAction, (state, action) => ({
+ issues: [...state.issues, action.issue],
+ })),
+ on(receivedSolutionSuccessAction, (state, action) => ({
+ issues: {
+ ...state.issues.slice(
+ 0,
+ state.issues.findIndex((issue) => issue.id === action.issueId)
+ ),
+ state.issues[0],
+
+ ...state.issues.slice(
+ state.issues.findIndex((issue) => issue.id === action.issueId) + 1
+ ),
+ },
}))
);
diff --git a/apps/frontend/src/environments/environments.prod.ts b/apps/frontend/src/environments/environments.prod.ts
new file mode 100644
index 0000000..cb6c68d
--- /dev/null
+++ b/apps/frontend/src/environments/environments.prod.ts
@@ -0,0 +1,3 @@
+export const environments = {
+ apiUrl: 'http://www.server.pl',
+};
diff --git a/apps/frontend/src/environments/environments.ts b/apps/frontend/src/environments/environments.ts
new file mode 100644
index 0000000..6f5d035
--- /dev/null
+++ b/apps/frontend/src/environments/environments.ts
@@ -0,0 +1,4 @@
+// Dev
+export const environments = {
+ apiUrl: 'http://localhost',
+};