diff --git a/apps/client/src/app/services/api.service.ts b/apps/client/src/app/services/api.service.ts new file mode 100644 index 0000000..d8f4179 --- /dev/null +++ b/apps/client/src/app/services/api.service.ts @@ -0,0 +1,44 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { + Transaction, + User, + PagedCollection, +} from '@money-sprouts/shared/domain'; + +@Injectable({ + providedIn: 'root', +}) +export class ApiService { + /** + * TODO replace with .env variable + */ + private baseUrl = 'http://localhost:8081'; + + constructor(private http: HttpClient) {} + + getUsers(): Observable> { + return this.http.get>(`${this.baseUrl}/api/users/`); + } + + getUserById(id: string): Observable { + return this.http.get(`${this.baseUrl}/api/users/${id}`); + } + + getTransactions(): Observable> { + return this.http.get>( + `${this.baseUrl}/api/transactions/` + ); + } + + getTransactionById(id: string): Observable { + return this.http.get(`${this.baseUrl}/api/transactions/${id}`); + } + + getTransactionsByUserId(userId: string): Observable { + return this.http.get( + `${this.baseUrl}/api/users/${userId}/transactions` + ); + } +} diff --git a/apps/client/src/app/services/user.service.ts b/apps/client/src/app/services/user.service.ts index 29e751f..0088ec1 100644 --- a/apps/client/src/app/services/user.service.ts +++ b/apps/client/src/app/services/user.service.ts @@ -2,11 +2,6 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { BehaviorSubject, Observable, map, of, tap } from 'rxjs'; -export interface User { - username: string; - avatar: string; -} - @Injectable({ providedIn: 'root', }) diff --git a/libs/shared/domain/src/index.ts b/libs/shared/domain/src/index.ts index 58c28a1..5897d7e 100644 --- a/libs/shared/domain/src/index.ts +++ b/libs/shared/domain/src/index.ts @@ -1,2 +1,5 @@ -export * from './lib/models/user'; -export * from './lib/models/transaction'; +export * from './interfaces/user'; +export * from './interfaces/transaction'; +export * from './interfaces/types'; +export * from './interfaces/ApiResource'; +export * from './interfaces/Collection'; diff --git a/libs/shared/domain/src/interfaces/Collection.ts b/libs/shared/domain/src/interfaces/Collection.ts new file mode 100644 index 0000000..5be6bbe --- /dev/null +++ b/libs/shared/domain/src/interfaces/Collection.ts @@ -0,0 +1,21 @@ +import { ApiResource } from './types'; + +export interface Pagination { + 'hydra:first'?: string; + 'hydra:previous'?: string; + 'hydra:next'?: string; + 'hydra:last'?: string; +} + +export interface PagedCollection extends ApiResource { + '@context'?: string; + '@type'?: string; + 'hydra:firstPage'?: string; + 'hydra:itemsPerPage'?: number; + 'hydra:lastPage'?: string; + 'hydra:member'?: T[]; + 'hydra:nextPage'?: string; + 'hydra:search'?: object; + 'hydra:totalItems'?: number; + 'hydra:view'?: Pagination; +} diff --git a/libs/shared/domain/src/interfaces/dataAccess.ts b/libs/shared/domain/src/interfaces/dataAccess.ts new file mode 100644 index 0000000..82027fb --- /dev/null +++ b/libs/shared/domain/src/interfaces/dataAccess.ts @@ -0,0 +1,13 @@ +export const normalizeLinks = ( + value: string | string[] | undefined +): string[] => { + if (!value) { + return []; + } + + if (typeof value === "string") { + return value.split(","); + } + + return value; +}; diff --git a/libs/shared/domain/src/lib/interfaces/transaction.ts b/libs/shared/domain/src/interfaces/transaction.ts similarity index 91% rename from libs/shared/domain/src/lib/interfaces/transaction.ts rename to libs/shared/domain/src/interfaces/transaction.ts index 33073d8..cfa21ca 100644 --- a/libs/shared/domain/src/lib/interfaces/transaction.ts +++ b/libs/shared/domain/src/interfaces/transaction.ts @@ -1,5 +1,5 @@ export interface Transaction { - "@id"?: string; + '@id'?: string; title?: string; type?: number; value?: number; diff --git a/libs/shared/domain/src/interfaces/types.ts b/libs/shared/domain/src/interfaces/types.ts new file mode 100644 index 0000000..52c863b --- /dev/null +++ b/libs/shared/domain/src/interfaces/types.ts @@ -0,0 +1,22 @@ +export type TError = SubmissionError | Error | null; + +export interface ApiResource { + "@id": string; +} + +export interface SubmissionErrors { + [p: string]: string; +} + +export class SubmissionError extends Error { + private readonly _errors: SubmissionErrors; + + constructor(message: string, errors: SubmissionErrors) { + super(message); + this._errors = errors; + } + + public get errors(): SubmissionErrors { + return this._errors; + } +} diff --git a/libs/shared/domain/src/lib/interfaces/user.ts b/libs/shared/domain/src/interfaces/user.ts similarity index 85% rename from libs/shared/domain/src/lib/interfaces/user.ts rename to libs/shared/domain/src/interfaces/user.ts index 13f0746..2187b58 100644 --- a/libs/shared/domain/src/lib/interfaces/user.ts +++ b/libs/shared/domain/src/interfaces/user.ts @@ -1,8 +1,8 @@ export interface User { - "@id"?: string; + '@id'?: string; email?: string; name?: string; - roles?: any; + roles?: string[]; password?: string; allowance?: number; nextPayday?: Date; diff --git a/package.json b/package.json index be60354..d905845 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "start-client": "nx serve client", "start-server": "nx serve server", "build:dev": "nx run client:build --configuration=development", - "generate:interfaces": "npm init @api-platform/client http://localhost:8101/api/ libs/shared/domain/src/lib/ -- --generator typescript" + "generate:interfaces": "npm init @api-platform/client http://localhost:8101/api/ libs/shared/domain/src/ -- --generator typescript" }, "private": true, "dependencies": { diff --git a/src/Factory/UserFactory.php b/src/Factory/UserFactory.php index 092d9de..5c87579 100644 --- a/src/Factory/UserFactory.php +++ b/src/Factory/UserFactory.php @@ -45,7 +45,10 @@ protected function getDefaults(): array 'email' => self::faker()->email, 'name' => self::faker()->firstName, 'password' => self::faker()->password, - 'avatar' => self::faker()->randomElement(['/build/assets/images/avatar_female.png', '/build/assets/images/avatar_male.png']), + 'avatar' => self::faker()->randomElement([ + '/build/assets/images/avatar_female.png', + '/build/assets/images/avatar_male.png' + ]), 'roles' => [UserRole::USER], ]; }