diff --git a/arai-frontend/package.json b/arai-frontend/package.json index 0c2bad5..0e2c0e1 100644 --- a/arai-frontend/package.json +++ b/arai-frontend/package.json @@ -25,6 +25,7 @@ "@angular/router": "^17.0.0", "@angular/ssr": "^17.0.3", "express": "^4.18.2", + "faker": "^6.6.6", "json-server": "1.0.0-alpha.23", "rxjs": "~7.8.0", "socket.io-client": "^4.7.4", @@ -36,7 +37,9 @@ "@angular-devkit/build-angular": "^17.0.3", "@angular/cli": "^17.0.3", "@angular/compiler-cli": "^17.0.0", + "@faker-js/faker": "^8.4.1", "@types/express": "^4.17.17", + "@types/faker": "^6.6.9", "@types/jasmine": "~5.1.0", "@types/node": "^18.18.0", "@types/uuid": "^9.0.8", diff --git a/arai-frontend/pnpm-lock.yaml b/arai-frontend/pnpm-lock.yaml index 671e8d9..95a624b 100644 --- a/arai-frontend/pnpm-lock.yaml +++ b/arai-frontend/pnpm-lock.yaml @@ -47,6 +47,9 @@ dependencies: express: specifier: ^4.18.2 version: 4.18.3 + faker: + specifier: ^6.6.6 + version: 6.6.6 json-server: specifier: 1.0.0-alpha.23 version: 1.0.0-alpha.23 @@ -76,9 +79,15 @@ devDependencies: '@angular/compiler-cli': specifier: ^17.0.0 version: 17.2.4(@angular/compiler@17.2.4)(typescript@5.2.2) + '@faker-js/faker': + specifier: ^8.4.1 + version: 8.4.1 '@types/express': specifier: ^4.17.17 version: 4.17.21 + '@types/faker': + specifier: ^6.6.9 + version: 6.6.9 '@types/jasmine': specifier: ~5.1.0 version: 5.1.4 @@ -2260,6 +2269,11 @@ packages: dev: true optional: true + /@faker-js/faker@8.4.1: + resolution: {integrity: sha512-XQ3cU+Q8Uqmrbf2e0cIC/QN43sTBSC8KF12u29Mb47tWrt2hAgBXSgpZMj4Ao8Uk0iJcU99QsOCaIL8934obCg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0, npm: '>=6.14.13'} + dev: true + /@fastify/busboy@2.1.1: resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} engines: {node: '>=14'} @@ -3503,6 +3517,13 @@ packages: '@types/serve-static': 1.15.5 dev: true + /@types/faker@6.6.9: + resolution: {integrity: sha512-Y9YYm5L//8ooiiknO++4Gr539zzdI0j3aXnOBjo1Vk+kTvffY10GuE2wn78AFPECwZ5MYGTjiDVw1naLLdDimw==} + deprecated: This is a stub types definition. faker provides its own type definitions, so you do not need this installed. + dependencies: + faker: 6.6.6 + dev: true + /@types/http-errors@2.0.4: resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} dev: true @@ -4913,6 +4934,9 @@ packages: tmp: 0.0.33 dev: true + /faker@6.6.6: + resolution: {integrity: sha512-9tCqYEDHI5RYFQigXFwF1hnCwcWCOJl/hmll0lr5D2Ljjb0o4wphb69wikeJDz5qCEzXCoPvG6ss5SDP6IfOdg==} + /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true diff --git a/arai-frontend/src/app/backend.service.ts b/arai-frontend/src/app/backend.service.ts index 4c9fb87..d9ddcc1 100644 --- a/arai-frontend/src/app/backend.service.ts +++ b/arai-frontend/src/app/backend.service.ts @@ -32,19 +32,16 @@ export class BackendService { } } - public sendMessage(message: UserInputRequest): Promise { + public sendMessage(message: GenericRequest): Promise { return new Promise((resolve, reject) => { if (message.request_type === "user_input") { this.userInputArray.push(message as UserInputRequest); } - - // Assuming `serializeToQueryParams` is a method that converts your message object into HttpParams. - // You will need to implement this conversion based on your `GenericRequest` structure. - const params = this.serializeToQueryParams(message); - - console.log(`request: `, params.toString()); - - this.http.get(`${this.address}`, { params }).subscribe({ + const headers = new HttpHeaders().set("Content-Type", "application/json"); + + console.log(`request: `, JSON.stringify(message)); + + this.http.post(this.address, JSON.stringify(message), { headers }).subscribe({ next: (response) => { console.log(`response: `, response); resolve(response); diff --git a/arai-frontend/src/app/case-input/case-input.component.html b/arai-frontend/src/app/case-input/case-input.component.html index b6078ec..2368579 100644 --- a/arai-frontend/src/app/case-input/case-input.component.html +++ b/arai-frontend/src/app/case-input/case-input.component.html @@ -1,5 +1,7 @@
+

Oblicz koszta i czas sporu

+ Opis Sprawy diff --git a/arai-frontend/src/app/case-input/case-input.component.scss b/arai-frontend/src/app/case-input/case-input.component.scss index 19a84b8..c14f097 100644 --- a/arai-frontend/src/app/case-input/case-input.component.scss +++ b/arai-frontend/src/app/case-input/case-input.component.scss @@ -5,6 +5,16 @@ body, html { align-items: center; margin: 0; } + +.center { + text-align: center; +} + +.page-container { + display: flex; + justify-content: center; + align-items: center; +} .lawyering-form { display: flex; @@ -28,7 +38,7 @@ body, html { .checkbox-group { display: flex; - flex-direction: column; + flex-direction: row; gap: 10px; // For spacing between checkboxes } @@ -38,6 +48,7 @@ body, html { color: #ffffff; font-size: 16px; font-weight: 500; + width: 100%; } } @@ -51,5 +62,11 @@ body, html { width: 100%; /* Makes the submit button full width on smaller screens */ align-self: center; /* Center align if preferred */ } + + .checkbox-group { + display: flex; + flex-direction: column; + gap: 10px; // For spacing between checkboxes + } } \ No newline at end of file diff --git a/arai-frontend/src/app/case-input/case-input.component.ts b/arai-frontend/src/app/case-input/case-input.component.ts index 25ae0df..1b41a0d 100644 --- a/arai-frontend/src/app/case-input/case-input.component.ts +++ b/arai-frontend/src/app/case-input/case-input.component.ts @@ -5,6 +5,7 @@ import { MatCheckboxModule } from '@angular/material/checkbox' import { MatButtonModule } from '@angular/material/button' import { BackendService } from '../backend.service'; import { GenericRequest, UserInputRequest, userInput } from '../requests-responses'; +import { Router } from '@angular/router'; @Component({ @@ -23,10 +24,10 @@ export class CaseInputComponent { userInputForm: FormGroup; userInput: userInput | null = null; - constructor(private fb: FormBuilder, private readonly backendService: BackendService) { + constructor(private fb: FormBuilder, private readonly backendService: BackendService, private readonly router: Router) { this.userInputForm = this.fb.group({ generic_input: [''], - trial_value: [0], + trial_value: [], location: [''], experts_called: [false], witnesses_called: [false] @@ -37,7 +38,8 @@ export class CaseInputComponent { this.userInput = this.userInputForm.value; if(this.userInput !== null) { const result = await this.backendService.sendMessage(new UserInputRequest(this.userInput)); - console.log(`result: `, result); + console.log(`result: `, result); + this.router.navigate(['koszt']); } else { console.error(`caseInputComponent, onSubmit, userInput is null!`) } diff --git a/arai-frontend/src/app/cost-view/cost-view.component.html b/arai-frontend/src/app/cost-view/cost-view.component.html index aadef5b..324bb44 100644 --- a/arai-frontend/src/app/cost-view/cost-view.component.html +++ b/arai-frontend/src/app/cost-view/cost-view.component.html @@ -1,5 +1,15 @@ -Przewidywalne minimalne koszta: -@if(costData !== null) { - Koszta: {{costData.cost_of_trial}} zł
- Przewidywalny czas: {{costData.time_of_trial | date:'L'}} miesiące -} \ No newline at end of file + + + +

Chcesz zminimalizować koszta aż o 90%?

+
+ +
\ No newline at end of file diff --git a/arai-frontend/src/app/cost-view/cost-view.component.scss b/arai-frontend/src/app/cost-view/cost-view.component.scss index e69de29..b8d2ff5 100644 --- a/arai-frontend/src/app/cost-view/cost-view.component.scss +++ b/arai-frontend/src/app/cost-view/cost-view.component.scss @@ -0,0 +1,44 @@ +.legal-costs { + font-family: 'Times New Roman', serif; + color: #2a2a2a; // Dark text for readability + background-color: #f5f5f5; // Light background to keep the content subtle + padding: 20px; + border: 1px solid #ddd; // Slight border for definition + border-radius: 5px; // Soften the edges for a modern look + font-size: 16px; + + .cost-details { + margin-top: 10px; + padding: 10px; + background-color: #fff; // A clean background for the cost details + border-left: 5px solid #004085; // A striking left border for emphasis + font-size: 24px; + + span { + font-weight: bold; // Make the dynamic content pop + } + + .cost { + color: #007bff; // A professional blue for costs + } + + .time { + color: #28a745; // A hopeful green for the time + } + } + } + + +.bait { + text-align: center; +} + +.find-mediator { + width: 100%; +} + +.center-button { + display: flex; + justify-content: center; + align-items: center; +} \ No newline at end of file diff --git a/arai-frontend/src/app/cost-view/cost-view.component.ts b/arai-frontend/src/app/cost-view/cost-view.component.ts index d1f240c..3e7842e 100644 --- a/arai-frontend/src/app/cost-view/cost-view.component.ts +++ b/arai-frontend/src/app/cost-view/cost-view.component.ts @@ -1,11 +1,13 @@ import { Component, Input } from '@angular/core'; import { StatisticsOutputInterface } from '../requests-responses'; import { DatePipe } from '@angular/common'; +import { MatButtonModule } from '@angular/material/button'; +import { Router } from '@angular/router'; @Component({ selector: 'app-cost-view', standalone: true, - imports: [DatePipe], + imports: [DatePipe, MatButtonModule], templateUrl: './cost-view.component.html', styleUrl: './cost-view.component.scss' }) @@ -15,6 +17,8 @@ export class CostViewComponent { time_of_trial: Date.UTC(0, 6, 0, 0, 0, 0, 0) }; +constructor(private readonly router: Router) {} + public calculateTimeDifference(utcDateNumber: number): string { const currentDate = new Date(); const targetDate = new Date(utcDateNumber); @@ -40,4 +44,8 @@ public calculateTimeDifference(utcDateNumber: number): string { } } +onSubmit() { + this.router.navigate(["mediatorzy"]); +} + } diff --git a/arai-frontend/src/app/email-input/email-input.component.html b/arai-frontend/src/app/email-input/email-input.component.html new file mode 100644 index 0000000..f35d6aa --- /dev/null +++ b/arai-frontend/src/app/email-input/email-input.component.html @@ -0,0 +1,20 @@ +

Wprowadź email drugiej strony

+ +

Poinformujemy osobę o twojej chęci do podjęcia mediacji

+ + + Email + + @if (emailFormControl.hasError('email') && !emailFormControl.hasError('required')) { + Please enter a valid email address + } + @if (emailFormControl.hasError('required')) { + Email is required + } + + +
+ + + diff --git a/arai-frontend/src/app/email-input/email-input.component.scss b/arai-frontend/src/app/email-input/email-input.component.scss new file mode 100644 index 0000000..a6b073e --- /dev/null +++ b/arai-frontend/src/app/email-input/email-input.component.scss @@ -0,0 +1,7 @@ +.center { + width: 100%; +} + +.title { + text-align: center; +} \ No newline at end of file diff --git a/arai-frontend/src/app/email-input/email-input.component.spec.ts b/arai-frontend/src/app/email-input/email-input.component.spec.ts new file mode 100644 index 0000000..348de29 --- /dev/null +++ b/arai-frontend/src/app/email-input/email-input.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EmailInputComponent } from './email-input.component'; + +describe('EmailInputComponent', () => { + let component: EmailInputComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [EmailInputComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(EmailInputComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/arai-frontend/src/app/email-input/email-input.component.ts b/arai-frontend/src/app/email-input/email-input.component.ts new file mode 100644 index 0000000..97217cf --- /dev/null +++ b/arai-frontend/src/app/email-input/email-input.component.ts @@ -0,0 +1,25 @@ +import { Component, Inject } from '@angular/core'; +import { FormControl, Validators } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import {MAT_DIALOG_DATA, MatDialogModule, MatDialogRef} from '@angular/material/dialog' +import { MatInputModule } from '@angular/material/input'; + +@Component({ + selector: 'app-email-input', + standalone: true, + imports: [MatDialogModule, MatInputModule, MatButtonModule], + templateUrl: './email-input.component.html', + styleUrl: './email-input.component.scss' +}) +export class EmailInputComponent { + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any) {} + + emailFormControl = new FormControl('', [Validators.required, Validators.email]); + + + onNoClick(): void { + this.dialogRef.close(); + } +} diff --git a/arai-frontend/src/app/mediators-list/mediators-list.component.html b/arai-frontend/src/app/mediators-list/mediators-list.component.html index a90591c..8bdc7de 100644 --- a/arai-frontend/src/app/mediators-list/mediators-list.component.html +++ b/arai-frontend/src/app/mediators-list/mediators-list.component.html @@ -1,32 +1,29 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
No. {{element.position}} Name {{element.name}} Weight {{element.weight}} Symbol {{element.symbol}}
\ No newline at end of file +
+@for(mediator of mediatorzy; track mediator) { + + +
+ {{ mediator.name }} + + {{ mediator.specialization }} +
+
+ {{ convertToStars(mediator.ai_rating) }} +
+ Liczba opinii: {{ mediator.number_of_opinions }} +
+
+
+ +

+ location_on {{ generateCity() }} {{ generateAddress() }}
+ attach_money Cena za godzinę: {{ generateCost() }} zł
+ @if(generateOnline()) { class="available">Mediacja zdalna } +

+
+ + + +
+} +
\ No newline at end of file diff --git a/arai-frontend/src/app/mediators-list/mediators-list.component.scss b/arai-frontend/src/app/mediators-list/mediators-list.component.scss index e69de29..5fd3c4a 100644 --- a/arai-frontend/src/app/mediators-list/mediators-list.component.scss +++ b/arai-frontend/src/app/mediators-list/mediators-list.component.scss @@ -0,0 +1,32 @@ +.example-card { + width: 350px; +} + +.example-header-image { + background-size: cover; + width: 40px; /* Example size, adjust as needed */ + height: 40px; /* Example size, adjust as needed */ + border-radius: 50%; /* Makes the image round */ +} + +.golden-star { + color: gold; +} + +.ratings-row { + display: flex; + align-items: center; + gap: 10px; +} + +.available { + color: green; +} + +.center { + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; + gap: 20px; +} diff --git a/arai-frontend/src/app/mediators-list/mediators-list.component.ts b/arai-frontend/src/app/mediators-list/mediators-list.component.ts index cba0990..f030287 100644 --- a/arai-frontend/src/app/mediators-list/mediators-list.component.ts +++ b/arai-frontend/src/app/mediators-list/mediators-list.component.ts @@ -1,34 +1,102 @@ -import { Component } from '@angular/core'; +import { Component, Input } from '@angular/core'; import { MatTableModule } from '@angular/material/table' - -export interface PeriodicElement { - name: string; - position: number; - weight: number; - symbol: string; -} - -const ELEMENT_DATA: PeriodicElement[] = [ - {position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H'}, - {position: 2, name: 'Helium', weight: 4.0026, symbol: 'He'}, - {position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li'}, - {position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be'}, - {position: 5, name: 'Boron', weight: 10.811, symbol: 'B'}, - {position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C'}, - {position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N'}, - {position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O'}, - {position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F'}, - {position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne'}, -]; +import { RecommendedMediatorsInterface } from '../requests-responses'; +import { MatCardModule } from '@angular/material/card' +import { MatButtonModule } from '@angular/material/button'; +import { faker } from '@faker-js/faker'; +import {MatIconModule } from '@angular/material/icon' +import { MatDialog } from '@angular/material/dialog'; +import { EmailInputComponent } from '../email-input/email-input.component'; @Component({ selector: 'app-mediators-list', standalone: true, - imports: [MatTableModule], + imports: [MatTableModule, MatCardModule, MatButtonModule, MatIconModule], templateUrl: './mediators-list.component.html', styleUrl: './mediators-list.component.scss' }) export class MediatorsListComponent { - displayedColumns: string[] = ['position', 'name', 'weight', 'symbol']; - dataSource = ELEMENT_DATA; + @Input() mediatorzy: RecommendedMediatorsInterface[] = [ + { + "name": "Mateusz Szpyruk", + "specialization": "Prawo podatkowe", + "localization": "Katowice", + "ai_rating": 99, + "user_rating": 99, + "number_of_opinions": 5 + }, + { + "name": "Jan Kowalski", + "specialization": "Prawo pracy", + "localization": "Katowice", + "ai_rating": 90, + "user_rating": 99, + "number_of_opinions": 5 + }, + { + "name": "Jan Kowalski", + "specialization": "Prawo pracy", + "localization": "Katowice", + "ai_rating": 76, + "user_rating": 99, + "number_of_opinions": 5 + } +] + +constructor(private readonly dialog: MatDialog) {} + +generatePersonInfo() { + const personInfo = { + firstName: faker.name.firstName(), + lastName: faker.name.lastName(), + email: faker.internet.email(), + avatar: faker.image.avatar() // Generating person image + }; + console.log(`faker.image.avatar(): `, faker.image.avatar()); + const avatarUrl = personInfo.avatar; + return avatarUrl; +} + +convertToStars(score: number): string { + if (score < 0 || score > 100) { + return 'Score must be between 0 and 100'; + } + + // Calculate the number of full stars + const fullStars = Math.floor(score / 20); + // Determine if there should be a half star + const halfStar = (score % 20) >= 10 ? 1 : 0; + // Calculate the number of empty stars + const emptyStars = 5 - fullStars - halfStar; + + return '★'.repeat(fullStars) + '✩'.repeat(halfStar) + '☆'.repeat(emptyStars); +} + +generateCity() { + return faker.location.city(); +} + +generateAddress() { + return faker.location.streetAddress(); +} + +generateCost() { + return faker.commerce.price(); +} + +generateOnline() { + return faker.datatype.boolean(); +} + +umowSie() { + const dialogRef = this.dialog.open(EmailInputComponent, { + width: '250px', + data: { /* Data passed to the modal */ } + }); + + dialogRef.afterClosed().subscribe(result => { + console.log('The dialog was closed'); + // Optional: handle data returned from the modal + }); +} } diff --git a/arai-frontend/src/app/requests-responses.ts b/arai-frontend/src/app/requests-responses.ts index 45d866d..c77f39d 100644 --- a/arai-frontend/src/app/requests-responses.ts +++ b/arai-frontend/src/app/requests-responses.ts @@ -48,7 +48,8 @@ export interface RecommendedMediatorsInterface { "name": string, "specialization": string, "localization": string, - "score": number, + "ai_rating": number, + "user_rating": number, "number_of_opinions": number }