diff --git a/angular.json b/angular.json index 93b2559..f730ce7 100644 --- a/angular.json +++ b/angular.json @@ -53,7 +53,13 @@ "development": { "optimization": false, "extractLicenses": false, - "sourceMap": true + "sourceMap": true, + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.development.ts" + } + ] } }, "defaultConfiguration": "production" diff --git a/src/app/app.component.html b/src/app/app.component.html index 36093e1..12b5d24 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,336 +1 @@ - - - - - - - - - - - -
-
-
- -

Hello, {{ title }}

-

Congratulations! Your app is running. 🎉

-
- -
-
- @for (item of [ - { title: 'Explore the Docs', link: 'https://angular.dev' }, - { title: 'Learn with Tutorials', link: 'https://angular.dev/tutorials' }, - { title: 'CLI Docs', link: 'https://angular.dev/tools/cli' }, - { title: 'Angular Language Service', link: 'https://angular.dev/tools/language-service' }, - { title: 'Angular DevTools', link: 'https://angular.dev/tools/devtools' }, - ]; track item.title) { - - {{ item.title }} - - - - - } -
- -
-
-
- - - - - - - - - - - + \ No newline at end of file diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 9d39c38..9292758 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -9,5 +9,4 @@ import { RouterOutlet } from '@angular/router'; styleUrl: './app.component.scss' }) export class AppComponent { - title = 'todo-app-angular'; } diff --git a/src/app/app.config.ts b/src/app/app.config.ts index 6c6ef60..91081fa 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -1,8 +1,8 @@ -import { ApplicationConfig } from '@angular/core'; -import { provideRouter } from '@angular/router'; +import { ApplicationConfig } from '@angular/core' +import { provideRouter, withComponentInputBinding } from '@angular/router' -import { routes } from './app.routes'; +import { routes } from './app.routes' export const appConfig: ApplicationConfig = { - providers: [provideRouter(routes)] -}; + providers: [provideRouter(routes, withComponentInputBinding())], +} diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index dc39edb..2306edb 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -1,3 +1,39 @@ -import { Routes } from '@angular/router'; +import { Routes } from '@angular/router' +import { HomeComponent } from './pages/home/home.component' +import { TodoPageComponent } from './pages/todo-page/todo-page.component' +import { TodoCreateComponent } from './pages/todo-create/todo-create.component' +import { TodoEditComponent } from './pages/todo-edit/todo-edit.component' +import { PageNotFoundComponent } from './pages/page-not-found/page-not-found.component' +import { TodoDetailComponent } from './pages/todo-detail/todo-detail.component' -export const routes: Routes = []; +export const routes: Routes = [ + { + path: '', + component: HomeComponent, + title: 'Home', + }, + { + path: 'list', + component: TodoPageComponent, + title: 'TODO', + }, + { + path: 'todo/:id', + component: TodoDetailComponent, + title: 'TODO Detail', + }, + { + path: 'create', + component: TodoCreateComponent, + title: 'Add TODO', + }, + { + path: 'edit/:id', + component: TodoEditComponent, + title: 'Edit TODO', + }, + { + path: '**', + component: PageNotFoundComponent, + }, +] diff --git a/src/app/components/todo/todo-item/todo-item.component.html b/src/app/components/todo/todo-item/todo-item.component.html new file mode 100644 index 0000000..d5a699b --- /dev/null +++ b/src/app/components/todo/todo-item/todo-item.component.html @@ -0,0 +1,3 @@ +
  • + {{ todo.title }} +
  • diff --git a/src/app/components/todo/todo-item/todo-item.component.scss b/src/app/components/todo/todo-item/todo-item.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/components/todo/todo-item/todo-item.component.spec.ts b/src/app/components/todo/todo-item/todo-item.component.spec.ts new file mode 100644 index 0000000..5521c5e --- /dev/null +++ b/src/app/components/todo/todo-item/todo-item.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TodoItemComponent } from './todo-item.component'; + +describe('TodoItemComponent', () => { + let component: TodoItemComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TodoItemComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TodoItemComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/todo/todo-item/todo-item.component.ts b/src/app/components/todo/todo-item/todo-item.component.ts new file mode 100644 index 0000000..2ff5cc5 --- /dev/null +++ b/src/app/components/todo/todo-item/todo-item.component.ts @@ -0,0 +1,15 @@ +import { Component, Input } from '@angular/core' +import { Todo } from '../../../models' +import { RouterLink } from '@angular/router' + +@Component({ + selector: 'app-todo-item', + standalone: true, + imports: [RouterLink], + templateUrl: './todo-item.component.html', + styleUrl: './todo-item.component.scss', +}) +export class TodoItemComponent { + @Input() + todo!: Todo +} diff --git a/src/app/components/todo/todo-list/todo-list.component.html b/src/app/components/todo/todo-list/todo-list.component.html new file mode 100644 index 0000000..33e5835 --- /dev/null +++ b/src/app/components/todo/todo-list/todo-list.component.html @@ -0,0 +1,3 @@ +
      + +
    diff --git a/src/app/components/todo/todo-list/todo-list.component.scss b/src/app/components/todo/todo-list/todo-list.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/components/todo/todo-list/todo-list.component.spec.ts b/src/app/components/todo/todo-list/todo-list.component.spec.ts new file mode 100644 index 0000000..6ca0ced --- /dev/null +++ b/src/app/components/todo/todo-list/todo-list.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TodoListComponent } from './todo-list.component'; + +describe('TodoListComponent', () => { + let component: TodoListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TodoListComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TodoListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/todo/todo-list/todo-list.component.ts b/src/app/components/todo/todo-list/todo-list.component.ts new file mode 100644 index 0000000..7c41221 --- /dev/null +++ b/src/app/components/todo/todo-list/todo-list.component.ts @@ -0,0 +1,16 @@ +import { Component, Input } from '@angular/core' +import { Todo } from '../../../models' +import { TodoItemComponent } from '../todo-item/todo-item.component' +import { CommonModule } from '@angular/common' + +@Component({ + selector: 'app-todo-list', + standalone: true, + imports: [TodoItemComponent, CommonModule], + templateUrl: './todo-list.component.html', + styleUrl: './todo-list.component.scss', +}) +export class TodoListComponent { + @Input() + todoList!: Todo[] +} diff --git a/src/app/models.ts b/src/app/models.ts new file mode 100644 index 0000000..289af12 --- /dev/null +++ b/src/app/models.ts @@ -0,0 +1,29 @@ +export type TodoState = 0 | 1 | 2 + +export type Todo = { + id: number + category: TodoCategory | null + title: string + body: string + state: TodoState +} + +export type TodoCreate = { + categoryId: number + title: string + body: string +} + +export type TodoUpdate = { + id: number + categoryId: number + title: string + body: string + state: TodoState +} + +export type TodoCategory = { + id: number + name: string + color: string +} diff --git a/src/app/pages/home/home.component.html b/src/app/pages/home/home.component.html new file mode 100644 index 0000000..216679e --- /dev/null +++ b/src/app/pages/home/home.component.html @@ -0,0 +1,3 @@ + diff --git a/src/app/pages/home/home.component.scss b/src/app/pages/home/home.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/home/home.component.spec.ts b/src/app/pages/home/home.component.spec.ts new file mode 100644 index 0000000..60c47c4 --- /dev/null +++ b/src/app/pages/home/home.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HomeComponent } from './home.component'; + +describe('HomeComponent', () => { + let component: HomeComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HomeComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(HomeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/home/home.component.ts b/src/app/pages/home/home.component.ts new file mode 100644 index 0000000..deb69c4 --- /dev/null +++ b/src/app/pages/home/home.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-home', + standalone: true, + imports: [], + templateUrl: './home.component.html', + styleUrl: './home.component.scss' +}) +export class HomeComponent { + +} diff --git a/src/app/pages/page-not-found/page-not-found.component.html b/src/app/pages/page-not-found/page-not-found.component.html new file mode 100644 index 0000000..a50502a --- /dev/null +++ b/src/app/pages/page-not-found/page-not-found.component.html @@ -0,0 +1 @@ +

    Page Not Found.

    diff --git a/src/app/pages/page-not-found/page-not-found.component.scss b/src/app/pages/page-not-found/page-not-found.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/page-not-found/page-not-found.component.spec.ts b/src/app/pages/page-not-found/page-not-found.component.spec.ts new file mode 100644 index 0000000..19ef971 --- /dev/null +++ b/src/app/pages/page-not-found/page-not-found.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PageNotFoundComponent } from './page-not-found.component'; + +describe('PageNotFoundComponent', () => { + let component: PageNotFoundComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PageNotFoundComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PageNotFoundComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/page-not-found/page-not-found.component.ts b/src/app/pages/page-not-found/page-not-found.component.ts new file mode 100644 index 0000000..11ff605 --- /dev/null +++ b/src/app/pages/page-not-found/page-not-found.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-page-not-found', + standalone: true, + imports: [], + templateUrl: './page-not-found.component.html', + styleUrl: './page-not-found.component.scss' +}) +export class PageNotFoundComponent { + +} diff --git a/src/app/pages/todo-create/todo-create.component.html b/src/app/pages/todo-create/todo-create.component.html new file mode 100644 index 0000000..9d16359 --- /dev/null +++ b/src/app/pages/todo-create/todo-create.component.html @@ -0,0 +1,27 @@ +
    + + +
    +

    + title is required. +

    +
    + + + +
    +

    + TODO body is required. +

    +
    + + + + + + +
    diff --git a/src/app/pages/todo-create/todo-create.component.scss b/src/app/pages/todo-create/todo-create.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/todo-create/todo-create.component.spec.ts b/src/app/pages/todo-create/todo-create.component.spec.ts new file mode 100644 index 0000000..93210df --- /dev/null +++ b/src/app/pages/todo-create/todo-create.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TodoCreateComponent } from './todo-create.component'; + +describe('TodoCreateComponent', () => { + let component: TodoCreateComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TodoCreateComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TodoCreateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/todo-create/todo-create.component.ts b/src/app/pages/todo-create/todo-create.component.ts new file mode 100644 index 0000000..78961b2 --- /dev/null +++ b/src/app/pages/todo-create/todo-create.component.ts @@ -0,0 +1,80 @@ +import { Component } from '@angular/core' +import { TodoCategory, TodoCreate } from '../../models' +import { CommonModule } from '@angular/common' +import { + FormControl, + FormGroup, + ReactiveFormsModule, + Validators, +} from '@angular/forms' +import { TodoService } from '../../services/todo-service' +import { TodoCategoryService } from '../../services/todo-category-service' +import { Router } from '@angular/router' +import { toInt } from '../../utils/converter' + +@Component({ + selector: 'app-todo-create', + standalone: true, + imports: [CommonModule, ReactiveFormsModule], + templateUrl: './todo-create.component.html', + styleUrl: './todo-create.component.scss', +}) +export class TodoCreateComponent { + public readonly formGroup = new FormGroup({ + title: new FormControl('', Validators.required), + body: new FormControl('', Validators.required), + category: new FormControl(''), + }) + + public categoryListPromise: Promise | null = null + + public constructor( + private readonly router: Router, + private readonly todoService: TodoService, + private readonly todoCategoryService: TodoCategoryService + ) {} + + public ngOnInit() { + this.categoryListPromise = this.todoCategoryService.getAll() + } + + // form getters + + get titleForm() { + return this.formGroup.controls.title + } + + get bodyForm() { + return this.formGroup.controls.body + } + + get categoryForm() { + return this.formGroup.controls.category + } + + // event handlers + + public async onCreateClicked() { + const formData = this.getFormData() + + if (formData == null) { + return + } + + await this.todoService.create(formData) + + this.router.navigate(['/list']) + } + + private getFormData(): TodoCreate | null { + if (this.formGroup.invalid) { + return null + } + + return { + categoryId: toInt(this.formGroup.value.category!), + title: this.formGroup.value.title!, + body: this.formGroup.value.body!, + } + } +} diff --git a/src/app/pages/todo-detail/todo-detail.component.html b/src/app/pages/todo-detail/todo-detail.component.html new file mode 100644 index 0000000..520a58b --- /dev/null +++ b/src/app/pages/todo-detail/todo-detail.component.html @@ -0,0 +1,15 @@ + +

    {{ todo.title }}

    +

    {{ todo.body }}

    +

    カテゴリ

    +

    {{ todo.category?.name }}

    +

    ステータス

    +

    {{ todo.state }}

    +

    操作

    + +
    diff --git a/src/app/pages/todo-detail/todo-detail.component.scss b/src/app/pages/todo-detail/todo-detail.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/todo-detail/todo-detail.component.spec.ts b/src/app/pages/todo-detail/todo-detail.component.spec.ts new file mode 100644 index 0000000..87a420a --- /dev/null +++ b/src/app/pages/todo-detail/todo-detail.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TodoDetailComponent } from './todo-detail.component'; + +describe('TodoDetailComponent', () => { + let component: TodoDetailComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TodoDetailComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TodoDetailComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/todo-detail/todo-detail.component.ts b/src/app/pages/todo-detail/todo-detail.component.ts new file mode 100644 index 0000000..7bcdba4 --- /dev/null +++ b/src/app/pages/todo-detail/todo-detail.component.ts @@ -0,0 +1,32 @@ +import { Component, Input } from '@angular/core' +import { Todo } from '../../models' +import { Router, RouterLink } from '@angular/router' +import { CommonModule } from '@angular/common' +import { TodoService } from '../../services/todo-service' +import { toInt } from '../../utils/converter' + +@Component({ + selector: 'app-todo-detail', + standalone: true, + imports: [RouterLink, CommonModule], + templateUrl: './todo-detail.component.html', + styleUrl: './todo-detail.component.scss', +}) +export class TodoDetailComponent { + public todoPromise: Promise | null = null + + constructor( + private readonly router: Router, + private readonly todoService: TodoService + ) {} + + @Input() + set id(todoId: string) { + this.todoPromise = this.todoService.getTodo(toInt(todoId)) + } + + public async onRemoveClicked(id: number) { + await this.todoService.remove(id) + this.router.navigate(['/list']) + } +} diff --git a/src/app/pages/todo-edit/todo-edit.component.html b/src/app/pages/todo-edit/todo-edit.component.html new file mode 100644 index 0000000..f895e1b --- /dev/null +++ b/src/app/pages/todo-edit/todo-edit.component.html @@ -0,0 +1,34 @@ +
    + + +
    +

    + title is required. +

    +
    + + + +
    +

    + TODO body is required. +

    +
    + + + + + + + + + +
    diff --git a/src/app/pages/todo-edit/todo-edit.component.scss b/src/app/pages/todo-edit/todo-edit.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/todo-edit/todo-edit.component.spec.ts b/src/app/pages/todo-edit/todo-edit.component.spec.ts new file mode 100644 index 0000000..24fdfe4 --- /dev/null +++ b/src/app/pages/todo-edit/todo-edit.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TodoEditComponent } from './todo-edit.component'; + +describe('TodoEditComponent', () => { + let component: TodoEditComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TodoEditComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TodoEditComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/todo-edit/todo-edit.component.ts b/src/app/pages/todo-edit/todo-edit.component.ts new file mode 100644 index 0000000..b3d06ae --- /dev/null +++ b/src/app/pages/todo-edit/todo-edit.component.ts @@ -0,0 +1,111 @@ +import { Component, Input } from '@angular/core' +import { + FormControl, + FormGroup, + ReactiveFormsModule, + Validators, +} from '@angular/forms' +import { TodoCategory, TodoState, TodoUpdate } from '../../models' +import { CommonModule } from '@angular/common' +import { TodoService } from '../../services/todo-service' +import { toInt } from '../../utils/converter' +import { TodoCategoryService } from '../../services/todo-category-service' +import { Router } from '@angular/router' + +@Component({ + selector: 'app-todo-edit', + standalone: true, + imports: [CommonModule, ReactiveFormsModule], + templateUrl: './todo-edit.component.html', + styleUrl: './todo-edit.component.scss', +}) +export class TodoEditComponent { + public readonly formGroup = new FormGroup({ + id: new FormControl(null, Validators.required), + title: new FormControl('', Validators.required), + body: new FormControl('', Validators.required), + category: new FormControl(''), + state: new FormControl('', [Validators.min(0), Validators.max(2)]), + }) + + public categoryListPromise: Promise | null = null + + constructor( + private readonly router: Router, + private readonly todoService: TodoService, + private readonly todoCategoryService: TodoCategoryService + ) {} + + public ngOnInit() { + this.categoryListPromise = this.todoCategoryService.getAll() + } + + // path parameters + + @Input() + set id(todoId: string) { + this._loadTodo(toInt(todoId)) + } + + // form controls + + private get formId() { + return this.formGroup.controls.id + } + + get formTitle() { + return this.formGroup.controls.title + } + + get formBody() { + return this.formGroup.controls.body + } + + get formCategory() { + return this.formGroup.controls.category + } + + get formState() { + return this.formGroup.controls.state + } + + private async _loadTodo(todoId: number) { + const todo = await this.todoService.getTodo(todoId) + + this.formId.setValue(todo.id) + this.formTitle.setValue(todo.title) + this.formBody.setValue(todo.body) + this.formCategory.setValue(todo.category?.id.toString() ?? '') + this.formState.setValue(todo.state.toString()) + } + + private getFormData(): TodoUpdate | null { + if (this.formGroup.invalid) { + return null + } + + return { + id: this.formId.value!, + categoryId: toInt(this.formCategory.value!), + title: this.formTitle.value!, + body: this.formBody.value!, + state: toInt( + this.formState.value! + ) as TodoState /* Validator を通ってるなら 0-2 の数値であることが確定している */, + } + } + + // event handlers + + public async onEditClicked() { + const formData = this.getFormData() + + if (formData == null) { + return + } + + await this.todoService.update(formData) + + this.router.navigate(['/list']) + } +} diff --git a/src/app/pages/todo-page/todo-page.component.html b/src/app/pages/todo-page/todo-page.component.html new file mode 100644 index 0000000..9cd890c --- /dev/null +++ b/src/app/pages/todo-page/todo-page.component.html @@ -0,0 +1,2 @@ + +追加 diff --git a/src/app/pages/todo-page/todo-page.component.scss b/src/app/pages/todo-page/todo-page.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/todo-page/todo-page.component.spec.ts b/src/app/pages/todo-page/todo-page.component.spec.ts new file mode 100644 index 0000000..31a9f10 --- /dev/null +++ b/src/app/pages/todo-page/todo-page.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TodoPageComponent } from './todo-page.component'; + +describe('TodoPageComponent', () => { + let component: TodoPageComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TodoPageComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TodoPageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/todo-page/todo-page.component.ts b/src/app/pages/todo-page/todo-page.component.ts new file mode 100644 index 0000000..72f7981 --- /dev/null +++ b/src/app/pages/todo-page/todo-page.component.ts @@ -0,0 +1,23 @@ +import { Component } from '@angular/core' +import { Todo } from '../../models' +import { TodoListComponent } from '../../components/todo/todo-list/todo-list.component' +import { RouterLink } from '@angular/router' +import { TodoService } from '../../services/todo-service' +import { CommonModule } from '@angular/common' + +@Component({ + selector: 'app-todo-page', + standalone: true, + imports: [TodoListComponent, RouterLink, CommonModule], + templateUrl: './todo-page.component.html', + styleUrl: './todo-page.component.scss', +}) +export class TodoPageComponent { + public todoListPromise: Promise | null = null + + public constructor(private readonly todoService: TodoService) {} + + public ngOnInit() { + this.todoListPromise = this.todoService.getAll() + } +} diff --git a/src/app/services/todo-category-service.ts b/src/app/services/todo-category-service.ts new file mode 100644 index 0000000..cd42b1f --- /dev/null +++ b/src/app/services/todo-category-service.ts @@ -0,0 +1,16 @@ +import { Injectable } from '@angular/core' +import { TodoCategory } from '../models' +import { environment } from '../../environments/environment' + +@Injectable({ + providedIn: 'root', +}) +export class TodoCategoryService { + public async getAll(): Promise { + const response = await fetch(`${environment.apiUrl}/todo-category/list`, { + method: 'GET', + }) + const todoCategoryList = await response.json() + return todoCategoryList + } +} diff --git a/src/app/services/todo-service.ts b/src/app/services/todo-service.ts new file mode 100644 index 0000000..a513bb9 --- /dev/null +++ b/src/app/services/todo-service.ts @@ -0,0 +1,50 @@ +import { Injectable } from '@angular/core' +import { Todo, TodoCreate, TodoUpdate } from '../models' +import { environment } from '../../environments/environment' + +@Injectable({ + providedIn: 'root', +}) +export class TodoService { + public async getTodo(todoId: number): Promise { + const response = await fetch(`${environment.apiUrl}/todo/${todoId}`, { + method: 'GET', + }) + const todo = await response.json() + return todo + } + + public async getAll(): Promise { + const response = await fetch(`${environment.apiUrl}/todo/list`, { + method: 'GET', + }) + const todoList = await response.json() + return todoList + } + + public async create(todo: TodoCreate) { + await fetch(`${environment.apiUrl}/todo`, { + method: 'POST', + body: JSON.stringify(todo), + headers: { + 'Content-Type': 'application/json', + }, + }) + } + + public async update(todo: TodoUpdate) { + await fetch(`${environment.apiUrl}/todo`, { + method: 'PUT', + body: JSON.stringify(todo), + headers: { + 'Content-Type': 'application/json', + }, + }) + } + + public async remove(id: number) { + await fetch(`${environment.apiUrl}/todo/${id}`, { + method: 'DELETE', + }) + } +} diff --git a/src/app/utils/converter.ts b/src/app/utils/converter.ts new file mode 100644 index 0000000..28a18f0 --- /dev/null +++ b/src/app/utils/converter.ts @@ -0,0 +1,5 @@ +export function toInt(s: string): number { + const v = parseInt(s, 10) + if (Number.isNaN(v)) throw new Error(`Invalid value: ${s}`) + return v +} diff --git a/src/environments/environment.development.ts b/src/environments/environment.development.ts new file mode 100644 index 0000000..3c5b84e --- /dev/null +++ b/src/environments/environment.development.ts @@ -0,0 +1,3 @@ +export const environment = { + apiUrl: 'http://localhost:9000', +} diff --git a/src/environments/environment.ts b/src/environments/environment.ts new file mode 100644 index 0000000..ce513b5 --- /dev/null +++ b/src/environments/environment.ts @@ -0,0 +1,3 @@ +export const environment = { + apiUrl: 'https://api.todo-app', +}