経緯
この記事は以下の記事の続き。第7回です。
第1回 全体計画~要件定義編
第2回 アーキテクチャ設計~データベース設計編
第3回 API設計~インフラ設計編
第4回 設計工程の振り返り編
第5回 コーディング~疎通編
第6回 画面デザイン編
第6.5回 画面デザイン編おまけ AAでATOMIC
ここまでやってきて、正直なところこのままでは全然だめ、、全然自動化できてない。。
というわけで、これまでのことを振り返って工程を見直すことにしました。
(画面デザインの回の時に「ソース再作成とかもう一回やれと言われたらバグ取りがめんどくさすぎてやりたくないなぁ、、」と思ったんだけど、裏を返すとめんどくさい作業を残したままなんだなぁということ)
仕切り直しのためにまた振り返りをしました。
これまではChatGPTを使っていましたが、ここからはGPTのAPIを使っていきます。
結果
結構色々試行錯誤したので途中経過は割愛しておきます。
ざっくりやったことを書くと
"ワークフローを定義してAPIで一括処理⇒エラーが出まくるのを手で修正(補助としてChatGPTを使う)。"です。
与えたお題は「銀行で使うCRMを作る」です。
出来上がった画面はこんな感じです↓
とりあえず出来上がったモックを置いておきますので、興味ある方は是非こちらで動作確認もしてみてください。
https://bank-crm-v1-mock.s3.ap-northeast-1.amazonaws.com/index.html
※モック(サーバー側は作ってない)なのでユーザー/パスワードは何入れても大丈夫です。
ソースはこちら
完全自動で出来上がったわけではなく、まだ全然手がかかる状態です。
動くように修正してレイアウトを少し調整して、、で作業時間的には3時間くらいはかかっています。。
とはいえ最初の頃のエラー率からするとだいぶエラー率は落ちてきてはいて、なんとか全く手直ししなくて済むor5分くらいで済むくらいまで改善していきたいところです。
今現状でも全部フルスクラッチするよりは多少楽かな?という気はしますが、、UI/UXが雑なのでちょっと微妙なところです。(なんと言ってもシステム名以外は丸投げで、どんな機能が出来上がっているのかは全く分からないので。。)
若手エンジニアの方が求職用ポートフォリオ作るときに使ってみるとかアリな気がします。
ちなみにアイコンはDeepFloyd IFを使いました。文字が出るっていいですね。
APIから出てきたものをどのように修正したか、修正前後のdiffを置いておきます。
diffで見ると結構大量に直しているように見えますが、コンポーネントの入れ替えとか、レイアウト修正と、ある程度パターン化されたエラーの訂正なのでとても退屈な作業です。
退屈な作業をChatGPTにやらせようとしたらより退屈な作業ばかりが残るという本末転倒感が凄くて遣る瀬無いです。
修正内容
diff --git a/src/app/api.interceptor.ts b/src/app/api.interceptor.ts
index 503f23b..4573dd7 100644
--- a/src/app/api.interceptor.ts
+++ b/src/app/api.interceptor.ts
@@ -16 +16 @@ export class ApiInterceptor implements HttpInterceptor {
- if (!environment.production) {
+ if (!environment.production && url.startsWith('api/')) {
diff --git a/src/app/app.component.html b/src/app/app.component.html
index 0680b43..5bc47ee 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -0,0 +1,2 @@
+<ng-container *ngIf="routerLink==='/login';then notauth;else authed"></ng-container>
+<ng-template #notauth>
@@ -1,0 +4,127 @@
+ <div style="width: 100%;text-align: center;margin-top: 20px;text-decoration: underline;color:#1976d2;cursor: pointer;font-size: 14px;"
+ (click)="openLicense()">license.</div>
+</ng-template>
+<ng-template #authed>
+ <mat-toolbar class="toolbar" style="display:flex;justify-content: space-between;" color="primary">
+ <div style="display: flex;align-items: center;gap: 30px;">
+ <img src="assets/images/logo.png" alt="CRM Logo" class="logo">
+ <span class="username">{{ user?.lastName }} {{ user?.firstName }}</span>
+ </div>
+ <div>
+ <button mat-icon-button routerLink="/dashboard">
+ <mat-icon>home</mat-icon>
+ </button>
+ <span class="spacer"></span>
+ <button mat-icon-button [matMenuTriggerFor]="userMenu">
+ <mat-icon>account_circle</mat-icon>
+ </button>
+ <mat-menu #userMenu="matMenu">
+ <!-- <button mat-menu-item routerLink="/profile"> -->
+ <button mat-menu-item>
+ <mat-icon>person</mat-icon>
+ <span>プロフィールを編集</span>
+ </button>
+ <button mat-menu-item (click)="openChangePasswordDialog()">
+ <mat-icon>lock</mat-icon>
+ <span>パスワードを変更</span>
+ </button>
+ <button mat-menu-item (click)="logout()">
+ <mat-icon>exit_to_app</mat-icon>
+ <span>ログアウト</span>
+ </button>
+ </mat-menu>
+ <button mat-icon-button [matMenuTriggerFor]="notificationsMenu">
+ <mat-icon>notifications</mat-icon>
+ </button>
+ <mat-menu #notificationsMenu="matMenu">
+ <div mat-menu-item *ngFor="let notification of notifications" class="notification">
+
+ <div class="notification-content">
+ <div class="notification-title">
+ <mat-icon>{{notification.icon}}</mat-icon>
+ {{ notification.title }}
+ </div>
+ <div style="display:flex;gap:10px;align-items: baseline;">
+ <span class="notification-time">{{ notification.time }}</span>
+ <div class="notification-message">{{ notification.message }}</div>
+ </div>
+ </div>
+ </div>
+ </mat-menu>
+ </div>
+ </mat-toolbar>
+ <div class="side">
+ <mat-nav-list style="width: 250px;background-color: #f5f5f5;height: calc(100vh - 77px);position: relative;">
+ <mat-list-item routerLink="/dashboard" routerLinkActive="active-link">
+ <mat-icon>dashboard</mat-icon>
+ <span class="link-text">ダッシュボード</span>
+ </mat-list-item>
+ <mat-list-item routerLink="/customer-management" routerLinkActive="active-link">
+ <mat-icon>people</mat-icon>
+ <span class="link-text">顧客管理</span>
+ </mat-list-item>
+ <mat-list-item routerLink="/sales-management" routerLinkActive="active-link">
+ <mat-icon>attach_money</mat-icon>
+ <span class="link-text">売上管理</span>
+ </mat-list-item>
+ <mat-list-item routerLink="/task-management" routerLinkActive="active-link">
+ <mat-icon>assignment</mat-icon>
+ <span class="link-text">タスク管理</span>
+ </mat-list-item>
+ <mat-list-item routerLink="/performance-reporting" routerLinkActive="active-link">
+ <mat-icon>bar_chart</mat-icon>
+ <span class="link-text">パフォーマンスレポート</span>
+ </mat-list-item>
+ <mat-list-item routerLink="/claims-handling" routerLinkActive="active-link">
+ <mat-icon>gavel</mat-icon>
+ <span class="link-text">クレーム処理</span>
+ </mat-list-item>
+ <mat-list-item routerLink="/reference-management" routerLinkActive="active-link">
+ <mat-icon>library_books</mat-icon>
+ <span class="link-text">参照管理</span>
+ </mat-list-item>
+ <mat-list-item routerLink="/sales-literature-management" routerLinkActive="active-link">
+ <mat-icon>description</mat-icon>
+ <span class="link-text">営業資料管理</span>
+ </mat-list-item>
+ <mat-list-item routerLink="/team-collaboration" routerLinkActive="active-link">
+ <mat-icon>group</mat-icon>
+ <span class="link-text">チームコラボレーション</span>
+ </mat-list-item>
+ <mat-list-item routerLink="/training-management" routerLinkActive="active-link">
+ <mat-icon>school</mat-icon>
+ <span class="link-text">トレーニング管理</span>
+ </mat-list-item>
+
+ <mat-list-item style="position: absolute;bottom: 0;" (click)="openLicense()">
+ <mat-icon>info</mat-icon>
+ <span class="link-text">LICENSE</span>
+ </mat-list-item>
+ </mat-nav-list>
+ <div style="padding: 20px;width: 0%;flex-grow: 1;">
+ <router-outlet></router-outlet>
+ </div>
+ </div>
+</ng-template>
+<ng-template #license>
+ <h1>Licenses</h1>
+ <div>
+ made with AI.
+ <table>
+ <thead>
+ <tr>
+ <th>Package</th>
+ <th>License</th>
+ <th>Repository</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr *ngFor="let item of licenses | keyvalue">
+ <td>{{ item.key }}</td>
+ <td>{{ item.value.licenses }}</td>
+ <td><a href="{{ item.value.repository }}">{{ item.value.repository }}</a></td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</ng-template>
\ No newline at end of file
diff --git a/src/app/app.component.scss b/src/app/app.component.scss
index e69de29..985f278 100644
--- a/src/app/app.component.scss
+++ b/src/app/app.component.scss
@@ -0,0 +1,66 @@
+.logo {
+ height: 64px;
+ margin-left: -16px;
+}
+
+.side {
+ display: flex;
+
+ mat-icon {
+ margin-right: 10px;
+ }
+
+ .active-link {
+ background-color: #e0e0e0;
+ }
+}
+
+.notification {
+ padding: 0 30px;
+ height: auto;
+
+ // mat-menu {
+ // width: 350px;
+ // max-height: 500px;
+ // overflow: auto;
+ // }
+
+ // mat-menu-item {
+ // display: flex;
+ // align-items: center;
+ // padding: 8px;
+ // }
+
+ mat-icon {
+ font-size: 24px;
+ margin-right: 12px;
+ color: #999;
+ }
+
+ .notification-content {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ margin-right: 12px;
+ color: #666;
+ }
+
+ .notification-title {
+ font-size: 16px;
+ font-weight: bold;
+ margin-bottom: 4px;
+ }
+
+ .notification-message {
+ font-size: 14px;
+ color: #333;
+ line-height: initial;
+ white-space: pre-wrap;
+ }
+
+ .notification-time {
+ margin-left: auto;
+ font-size: 12px;
+ color: #999;
+ }
+}
\ No newline at end of file
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 27c2123..d30548f 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1 +1,7 @@
-import { Component } from '@angular/core';
+import { Component, Input, TemplateRef, ViewChild } from '@angular/core';
+import { User } from './models';
+import { AuthService, UserService } from './services';
+import { MatMenu } from '@angular/material/menu';
+import { NavigationEnd, Router } from '@angular/router';
+import { HttpClient } from '@angular/common/http';
+import { MatDialog, MatDialogRef } from '@angular/material/dialog';
@@ -9 +15,51 @@ export class AppComponent {
- title = 'angular-002';
+
+ @Input() color: string;
+
+ @ViewChild('userMenu') userMenu: MatMenu;
+ @ViewChild('notificationsMenu') notificationsMenu: MatMenu;
+ @ViewChild('license') license: TemplateRef<any>;
+
+
+ routerLink = '/';
+ matMenuTriggerFor = 'matMenuTriggerFor';
+ matIcon = 'mat-icon';
+ notificationItem = 'notification-item';
+ notificationTitle = 'notification-title';
+ notificationMessage = 'notification-message';
+ user: User;
+ notifications = [
+ { icon: 'notifications', title: '新しいメッセージ', message: '山田様から新しいメッセージが届いています。', time: '12:34' },
+ { icon: 'account_circle', title: '新しいタスク', message: '新しいタスクが割り当てられました。', time: '14:56' }
+ ];
+
+ licenses = [];
+
+ constructor(private userService: UserService, private authService: AuthService, private router: Router, private httpClient: HttpClient, private dialog: MatDialog) {
+ this.httpClient.get('assets/LICENSE.json').subscribe((config: any) => {
+ this.licenses = config;
+ });
+ this.userService.getUserProfile().subscribe((user: User) => {
+ this.user = user;
+ });
+ this.router.events.subscribe(event => {
+ if (event instanceof NavigationEnd) {
+ this.routerLink = event.url;
+ }
+ });
+ }
+
+ ngOnInit(): void {
+ }
+
+ openChangePasswordDialog(): void {
+ // TODO: Implement method to open change password dialog
+ }
+
+ logout(): void {
+ this.authService.logout();
+ this.router.navigate(['/login']);
+ }
+
+ openLicense(): void {
+ this.dialog.open(this.license, { width: '800px' });
+ }
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index b4e4af3..e498d9b 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -1,2 +1 @@
-
-import { NgModule } from '@angular/core';
+import { NgModule, LOCALE_ID } from '@angular/core';
@@ -6,2 +5 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
-import { HttpClientModule } from '@angular/common/http';
-import { CommonModule } from '@angular/common';
+import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
@@ -8,0 +7,4 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { CommonModule, DatePipe, registerLocaleData } from '@angular/common';
+import localeJa from '@angular/common/locales/ja';
+// ロケールデータを登録
+registerLocaleData(localeJa);
@@ -35,0 +38,6 @@ import { MatSidenavModule } from '@angular/material/sidenav';
+import { MatChipsModule } from '@angular/material/chips';
+import { MatProgressBarModule } from '@angular/material/progress-bar';
+
+import { NgChartsModule } from 'ng2-charts';
+import 'chartjs-adapter-moment';
+import { MatTimepickerModule } from 'mat-timepicker';
@@ -56 +64 @@ import { TaskManagementComponent } from './pages/task-management/task-management
-import { TeamCollaborationComponent } from './pages/team-collaboration/team-collaboration.component';
+import { AddSharedInfoDialogComponent, TeamCollaborationComponent } from './pages/team-collaboration/team-collaboration.component';
@@ -77,0 +86 @@ import { TrainingParticipationComponent } from './parts/training-participation/t
+import { ApiInterceptor } from './api.interceptor';
@@ -87,0 +97,2 @@ imports: [
+ MatTimepickerModule,
+ NgChartsModule,
@@ -113,0 +125,2 @@ imports: [
+ MatChipsModule,
+ MatProgressBarModule,
@@ -153,0 +167,2 @@ declarations: [
+
+ AddSharedInfoDialogComponent,
@@ -155,0 +171,2 @@ providers: [
+ { provide: LOCALE_ID, useValue: 'ja-JP' },
+ DatePipe,
diff --git a/src/app/dialogs/claim-details-dialog/claim-details-dialog.component.html b/src/app/dialogs/claim-details-dialog/claim-details-dialog.component.html
index d4859ae..497b15f 100644
--- a/src/app/dialogs/claim-details-dialog/claim-details-dialog.component.html
+++ b/src/app/dialogs/claim-details-dialog/claim-details-dialog.component.html
@@ -7 +7 @@
- <div mat-line>{{claim.customerName}}</div>
+ <div mat-line>{{customer.lastName}} {{customer.firstName}}</div>
diff --git a/src/app/dialogs/claim-details-dialog/claim-details-dialog.component.ts b/src/app/dialogs/claim-details-dialog/claim-details-dialog.component.ts
index 42ea2f1..4ce4769 100644
--- a/src/app/dialogs/claim-details-dialog/claim-details-dialog.component.ts
+++ b/src/app/dialogs/claim-details-dialog/claim-details-dialog.component.ts
@@ -4,2 +4,2 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
-import { Claim, ClaimStatus } from '../../models';
-import { ClaimsService } from '../../services';
+import { Claim, ClaimStatus, Customer } from '../../models';
+import { ClaimsService, CustomerService } from '../../services';
@@ -15,0 +16 @@ export class ClaimDetailsDialogComponent implements OnInit {
+ customer: Customer = {} as Customer;
@@ -18,0 +20 @@ export class ClaimDetailsDialogComponent implements OnInit {
+ private customerService: CustomerService,
@@ -20 +22 @@ export class ClaimDetailsDialogComponent implements OnInit {
- @Inject(MAT_DIALOG_DATA) public data: { claimId: number }
+ @Inject(MAT_DIALOG_DATA) public data: { claim: Claim }
@@ -24,7 +26,4 @@ export class ClaimDetailsDialogComponent implements OnInit {
- this.claimsService.getClaimDetails(this.data.claimId).subscribe(
- (claim) => {
- this.claim = claim;
- },
- (error) => {
- console.error(error);
- // TODO: Display error message to user
+ this.claim = this.data.claim;
+ this.customerService.getCustomerDetails(this.claim.customerId).subscribe(
+ (customers) => {
+ this.customer = customers;
@@ -36 +35 @@ export class ClaimDetailsDialogComponent implements OnInit {
- this.claimsService.respondToClaim(this.claim.id, this.response, this.status).subscribe(
+ this.claimsService.respondToClaim(this.claim.id, this.response).subscribe(
diff --git a/src/app/dialogs/customer-details-dialog/customer-details-dialog.component.html b/src/app/dialogs/customer-details-dialog/customer-details-dialog.component.html
index 4d6fc41..d8d6591 100644
--- a/src/app/dialogs/customer-details-dialog/customer-details-dialog.component.html
+++ b/src/app/dialogs/customer-details-dialog/customer-details-dialog.component.html
@@ -2,2 +2,2 @@
- <mat-card-header>
- <mat-card-title>{{customer.firstName}} {{customer.lastName}}</mat-card-title>
+ <mat-card-header style="align-items: center;justify-content: space-between;">
+ <mat-card-title>{{customer.lastName}} {{customer.firstName}}</mat-card-title>
diff --git a/src/app/dialogs/customer-details-dialog/customer-details-dialog.component.ts b/src/app/dialogs/customer-details-dialog/customer-details-dialog.component.ts
index 34cc133..181d254 100644
--- a/src/app/dialogs/customer-details-dialog/customer-details-dialog.component.ts
+++ b/src/app/dialogs/customer-details-dialog/customer-details-dialog.component.ts
@@ -5 +5 @@ import { Customer, Sale, SalesData } from '../../models';
-import { CustomerService, SalesService } from '../../services';
+import { CustomerService, PerformanceService, SalesService } from '../../services';
@@ -13,3 +13,3 @@ export class CustomerDetailsDialogComponent implements OnInit {
- customer: Customer;
- sales: Sale[];
- salesData: SalesData[];
+ customer: Customer = {} as Customer;
+ sales: Sale[] = [];
+ salesData: SalesData[] = [];
@@ -19,0 +20 @@ export class CustomerDetailsDialogComponent implements OnInit {
+ private performanceService: PerformanceService,
@@ -21 +22 @@ export class CustomerDetailsDialogComponent implements OnInit {
- @Inject(MAT_DIALOG_DATA) public data: { customerId: number }
+ @Inject(MAT_DIALOG_DATA) public data: { customer: Customer }
@@ -25,3 +26 @@ export class CustomerDetailsDialogComponent implements OnInit {
- this.customerService.getCustomerDetails(this.data.customerId).subscribe((customer) => {
- this.customer = customer;
- });
+ this.customer = this.data.customer;
@@ -29 +28 @@ export class CustomerDetailsDialogComponent implements OnInit {
- this.sales = sales.filter((sale) => sale.customerId === this.data.customerId);
+ this.sales = sales.filter((sale) => sale.customerId === this.data.customer.id);
@@ -31,2 +30,2 @@ export class CustomerDetailsDialogComponent implements OnInit {
- this.salesService.getSalesPerformance().subscribe((salesData) => {
- this.salesData = salesData.filter((data) => data.id === this.data.customerId);
+ this.performanceService.getSalesPerformance().subscribe((salesData) => {
+ this.salesData = salesData.filter((data) => data.id === this.data.customer.id);
diff --git a/src/app/dialogs/forgot-password-dialog/forgot-password-dialog.component.ts b/src/app/dialogs/forgot-password-dialog/forgot-password-dialog.component.ts
index a1a623b..43db281 100644
--- a/src/app/dialogs/forgot-password-dialog/forgot-password-dialog.component.ts
+++ b/src/app/dialogs/forgot-password-dialog/forgot-password-dialog.component.ts
@@ -36,15 +36,15 @@ export class ForgotPasswordDialogComponent implements OnInit {
-<!-- src/app/dialogs/forgot-password-dialog.component.html -->
-<h2 mat-dialog-title>パスワードを忘れた場合</h2>
-<div mat-dialog-content>
- <p>パスワードをリセットするためのリンクを送信します。</p>
- <form>
- <mat-form-field>
- <mat-label>メールアドレス</mat-label>
- <input matInput type="email" [(ngModel)]="email" name="email" required />
- </mat-form-field>
- </form>
-</div>
-<div mat-dialog-actions>
- <button mat-button (click)="onCancel()">キャンセル</button>
- <button mat-button color="primary" (click)="onSubmit()">送信</button>
-</div>
\ No newline at end of file
+// <!-- src/app/dialogs/forgot-password-dialog.component.html -->
+// <h2 mat-dialog-title>パスワードを忘れた場合</h2>
+// <div mat-dialog-content>
+// <p>パスワードをリセットするためのリンクを送信します。</p>
+// <form>
+// <mat-form-field>
+// <mat-label>メールアドレス</mat-label>
+// <input matInput type="email" [(ngModel)]="email" name="email" required />
+// </mat-form-field>
+// </form>
+// </div>
+// <div mat-dialog-actions>
+// <button mat-button (click)="onCancel()">キャンセル</button>
+// <button mat-button color="primary" (click)="onSubmit()">送信</button>
+// </div>
\ No newline at end of file
diff --git a/src/app/dialogs/literature-details-dialog/literature-details-dialog.component.html b/src/app/dialogs/literature-details-dialog/literature-details-dialog.component.html
index f5e57d9..fed092e 100644
--- a/src/app/dialogs/literature-details-dialog/literature-details-dialog.component.html
+++ b/src/app/dialogs/literature-details-dialog/literature-details-dialog.component.html
@@ -30,0 +31,30 @@
+<!-- <h2 mat-dialog-title>{{ matDialogTitle }}</h2>
+<mat-dialog-content>
+ <mat-card>
+ <mat-list>
+ <mat-list-item>
+ <h3 matLine>Title:</h3>
+ <p matLine>{{ literature?.title }}</p>
+ </mat-list-item>
+ <mat-list-item>
+ <h3 matLine>Description:</h3>
+ <p matLine>{{ literature?.description }}</p>
+ </mat-list-item>
+ <mat-list-item>
+ <h3 matLine>Upload Date:</h3>
+ <p matLine>{{ literature?.uploadDate | date: dateFormat }}</p>
+ </mat-list-item>
+ <mat-list-item>
+ <h3 matLine>{{ fileTypeLabel }}:</h3>
+ <p matLine>{{ literature?.fileType }}</p>
+ </mat-list-item>
+ <mat-list-item>
+ <h3 matLine>{{ fileUrlLabel }}:</h3>
+ <p matLine>{{ literature?.fileUrl }}</p>
+ </mat-list-item>
+ </mat-list>
+ </mat-card>
+</mat-dialog-content>
+<mat-dialog-actions>
+ <button mat-button mat-dialog-close>Close</button>
+</mat-dialog-actions> -->
\ No newline at end of file
diff --git a/src/app/dialogs/literature-details-dialog/literature-details-dialog.component.ts b/src/app/dialogs/literature-details-dialog/literature-details-dialog.component.ts
index 74b7463..346947a 100644
--- a/src/app/dialogs/literature-details-dialog/literature-details-dialog.component.ts
+++ b/src/app/dialogs/literature-details-dialog/literature-details-dialog.component.ts
@@ -23 +23 @@ export class LiteratureDetailsDialogComponent implements OnInit {
- @Inject(MAT_DIALOG_DATA) public data: { literatureId: number }
+ @Inject(MAT_DIALOG_DATA) public data: { literature: SalesLiterature }
@@ -27,3 +27 @@ export class LiteratureDetailsDialogComponent implements OnInit {
- this.salesLiteratureService
- .getLiteratureDetails(this.data.literatureId)
- .subscribe((literature) => (this.literature = literature));
+ this.literature = this.data.literature;
@@ -32,32 +29,0 @@ export class LiteratureDetailsDialogComponent implements OnInit {
-//
-// <!-- src/app/dialogs/literature-details-dialog.component.html -->
-<h2 mat-dialog-title>{{ matDialogTitle }}</h2>
-<mat-dialog-content>
- <mat-card>
- <mat-list>
- <mat-list-item>
- <h3 matLine>Title:</h3>
- <p matLine>{{ literature?.title }}</p>
- </mat-list-item>
- <mat-list-item>
- <h3 matLine>Description:</h3>
- <p matLine>{{ literature?.description }}</p>
- </mat-list-item>
- <mat-list-item>
- <h3 matLine>Upload Date:</h3>
- <p matLine>{{ literature?.uploadDate | date: dateFormat }}</p>
- </mat-list-item>
- <mat-list-item>
- <h3 matLine>{{ fileTypeLabel }}:</h3>
- <p matLine>{{ literature?.fileType }}</p>
- </mat-list-item>
- <mat-list-item>
- <h3 matLine>{{ fileUrlLabel }}:</h3>
- <p matLine>{{ literature?.fileUrl }}</p>
- </mat-list-item>
- </mat-list>
- </mat-card>
-</mat-dialog-content>
-<mat-dialog-actions>
- <button mat-button mat-dialog-close>Close</button>
-</mat-dialog-actions>
\ No newline at end of file
diff --git a/src/app/dialogs/referral-details-dialog/referral-details-dialog.component.ts b/src/app/dialogs/referral-details-dialog/referral-details-dialog.component.ts
index 83bcb92..ba5c0c9 100644
--- a/src/app/dialogs/referral-details-dialog/referral-details-dialog.component.ts
+++ b/src/app/dialogs/referral-details-dialog/referral-details-dialog.component.ts
@@ -4,2 +4,2 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
-import { Referral } from '../../models';
-import { ReferenceService } from '../../services';
+import { Customer, Referral } from '../../models';
+import { CustomerService, ReferenceService } from '../../services';
@@ -13 +13,2 @@ export class ReferralDetailsDialogComponent implements OnInit {
- referral: Referral;
+ referral: Referral = {} as Referral;
+ customer: Customer;
@@ -16,3 +17,3 @@ export class ReferralDetailsDialogComponent implements OnInit {
- private referenceService: ReferenceService,
- private dialogRef: MatDialogRef<ReferralDetailsDialogComponent>,
- @Inject(MAT_DIALOG_DATA) public data: { referralId: number }
+ private customerService: CustomerService,
+ public dialogRef: MatDialogRef<ReferralDetailsDialogComponent>,
+ @Inject(MAT_DIALOG_DATA) public data: { referral: Referral }
@@ -22,3 +23,3 @@ export class ReferralDetailsDialogComponent implements OnInit {
- this.referenceService.getReferralDetails(this.data.referralId).subscribe(
- (referral: Referral) => {
- this.referral = referral;
+ this.customerService.getCustomerDetails(this.data.referral.customerId).subscribe(
+ (customer: Customer) => {
+ this.customer = customer;
@@ -29,0 +31 @@ export class ReferralDetailsDialogComponent implements OnInit {
+ this.referral = this.data.referral;
diff --git a/src/app/dialogs/task-details-dialog/task-details-dialog.component.html b/src/app/dialogs/task-details-dialog/task-details-dialog.component.html
index f150d9c..84451e2 100644
--- a/src/app/dialogs/task-details-dialog/task-details-dialog.component.html
+++ b/src/app/dialogs/task-details-dialog/task-details-dialog.component.html
@@ -0,0 +1,28 @@
+<mat-card>
+ <mat-card-title>{{ 'taskDetailsDialog.taskTitle' }}: {{ task.title }}</mat-card-title>
+ <mat-card-content>
+ <p>{{ 'taskDetailsDialog.taskDescription' }}: {{ task.description }}</p>
+ <p>{{ 'taskDetailsDialog.startDate' }}: {{ task.startDate | date:'shortDate' }}</p>
+ <p>{{ 'taskDetailsDialog.endDate' }}: {{ task.endDate | date:'shortDate' }}</p>
+ <mat-chip-list>
+ <mat-chip
+ [ngClass]="{'mat-primary': task.status === 'COMPLETED', 'mat-warn': task.status === 'CANCELED', 'mat-accent': task.status === 'IN_PROGRESS', 'mat-basic': task.status === 'NOT_STARTED'}">{{
+ task.status }}</mat-chip>
+ </mat-chip-list>
+ <mat-list *ngIf="task.reminder">
+ <h3 mat-subheader>{{ 'taskDetailsDialog.reminder' }}</h3>
+ <mat-list-item>
+ <div mat-list-avatar>
+ <mat-icon>alarm</mat-icon>
+ </div>
+ <div mat-line>{{ task.reminder.message }}</div>
+ <div mat-line class="mat-card-subtitle">{{ task.reminder.time | date:'shortTime' }}</div>
+ </mat-list-item>
+ </mat-list>
+ </mat-card-content>
+ <mat-card-actions>
+ <button mat-button (click)="dialogRef.close()">{{ 'taskDetailsDialog.close' }}</button>
+ </mat-card-actions>
+</mat-card>
+
+<!--
@@ -24,0 +53 @@
+-->
\ No newline at end of file
diff --git a/src/app/dialogs/task-details-dialog/task-details-dialog.component.ts b/src/app/dialogs/task-details-dialog/task-details-dialog.component.ts
index a866b09..031ac7e 100644
--- a/src/app/dialogs/task-details-dialog/task-details-dialog.component.ts
+++ b/src/app/dialogs/task-details-dialog/task-details-dialog.component.ts
@@ -36,28 +36,28 @@ export class TaskDetailsDialogComponent implements OnInit {
-<h2 mat-dialog-title>{{ 'taskDetailsDialog.taskTitle' | translate }}</h2>
-<mat-dialog-content>
- <mat-card>
- <mat-card-content>
- <h3>{{ task.title }}</h3>
- <p>{{ task.description }}</p>
- <mat-list>
- <mat-list-item>
- <strong>{{ 'taskDetailsDialog.startDate' | translate }}:</strong> {{ task.startDate | date }}
- </mat-list-item>
- <mat-list-item>
- <strong>{{ 'taskDetailsDialog.endDate' | translate }}:</strong> {{ task.endDate | date }}
- </mat-list-item>
- <mat-list-item>
- <strong>{{ 'taskDetailsDialog.status' | translate }}:</strong>
- <span matBadge="{{ task.status }}" [matBadgeColor]="task.status === 'COMPLETED' ? 'primary' : 'warn'"></span>
- </mat-list-item>
- <mat-list-item>
- <strong>{{ 'taskDetailsDialog.reminder' | translate }}:</strong>
- <app-reminder [reminder]="task.reminder" (setReminder)="setReminder($event)"></app-reminder>
- </mat-list-item>
- </mat-list>
- </mat-card-content>
- </mat-card>
-</mat-dialog-content>
-<mat-dialog-actions>
- <button mat-button (click)="closeDialog()">{{ 'taskDetailsDialog.close' | translate }}</button>
-</mat-dialog-actions>
\ No newline at end of file
+// <h2 mat-dialog-title>{{ 'taskDetailsDialog.taskTitle' | translate }}</h2>
+// <mat-dialog-content>
+// <mat-card>
+// <mat-card-content>
+// <h3>{{ task.title }}</h3>
+// <p>{{ task.description }}</p>
+// <mat-list>
+// <mat-list-item>
+// <strong>{{ 'taskDetailsDialog.startDate' | translate }}:</strong> {{ task.startDate | date }}
+// </mat-list-item>
+// <mat-list-item>
+// <strong>{{ 'taskDetailsDialog.endDate' | translate }}:</strong> {{ task.endDate | date }}
+// </mat-list-item>
+// <mat-list-item>
+// <strong>{{ 'taskDetailsDialog.status' | translate }}:</strong>
+// <span matBadge="{{ task.status }}" [matBadgeColor]="task.status === 'COMPLETED' ? 'primary' : 'warn'"></span>
+// </mat-list-item>
+// <mat-list-item>
+// <strong>{{ 'taskDetailsDialog.reminder' | translate }}:</strong>
+// <app-reminder [reminder]="task.reminder" (setReminder)="setReminder($event)"></app-reminder>
+// </mat-list-item>
+// </mat-list>
+// </mat-card-content>
+// </mat-card>
+// </mat-dialog-content>
+// <mat-dialog-actions>
+// <button mat-button (click)="closeDialog()">{{ 'taskDetailsDialog.close' | translate }}</button>
+// </mat-dialog-actions>
\ No newline at end of file
diff --git a/src/app/pages/claims-handling/claims-handling.component.html b/src/app/pages/claims-handling/claims-handling.component.html
index 18c7e6a..ee79932 100644
--- a/src/app/pages/claims-handling/claims-handling.component.html
+++ b/src/app/pages/claims-handling/claims-handling.component.html
@@ -48,2 +48,2 @@
-
-<app-claim-response-dialog [claim]="selectedClaim" (claimChange)="updateClaim($event)"></app-claim-response-dialog>
\ No newline at end of file
+<!-- TODO -->
+<!-- <app-claim-response-dialog [claim]="selectedClaim" (claimChange)="updateClaim($event)"></app-claim-response-dialog> -->
\ No newline at end of file
diff --git a/src/app/pages/claims-handling/claims-handling.component.ts b/src/app/pages/claims-handling/claims-handling.component.ts
index 56a7269..f13752a 100644
--- a/src/app/pages/claims-handling/claims-handling.component.ts
+++ b/src/app/pages/claims-handling/claims-handling.component.ts
@@ -6 +6 @@ import { MatDialog } from '@angular/material/dialog';
-import { ClaimDetailsDialog } from '../../dialogs/claim-details/claim-details.dialog';
+import { ClaimDetailsDialogComponent } from '../../dialogs/claim-details-dialog/claim-details-dialog.component';
@@ -42,5 +41,0 @@ export class ClaimsHandlingComponent implements OnInit {
- this.dialog.open(ClaimDetailsDialog, {
- data: {
- claim: this.selectedClaim
- }
- });
@@ -50 +45 @@ export class ClaimsHandlingComponent implements OnInit {
- const dialogRef = this.dialog.open(this.claimResponseDialog, {
+ const dialogRef = this.dialog.open(ClaimDetailsDialogComponent, {
diff --git a/src/app/pages/customer-management/customer-management.component.html b/src/app/pages/customer-management/customer-management.component.html
index 468edbe..a8035ce 100644
--- a/src/app/pages/customer-management/customer-management.component.html
+++ b/src/app/pages/customer-management/customer-management.component.html
@@ -34,2 +34,13 @@
- <tr mat-header-row *matHeaderRowDef="['firstName', 'lastName', 'email', 'segment']"></tr>
- <tr mat-row *matRowDef="let row; columns: ['firstName', 'lastName', 'email', 'segment']" (click)="onCustomerSelected(row)"></tr>
+ <ng-container matColumnDef="action">
+ <th mat-header-cell *matHeaderCellDef>アクション</th>
+ <td mat-cell *matCellDef="let customer">
+ <button mat-icon-button (click)="openCustomerDetailsDialog(customer)">
+ <mat-icon>visibility</mat-icon>
+ </button>
+ <button mat-icon-button (click)="onCustomerSelected(customer)">
+ <mat-icon>edit</mat-icon>
+ </button>
+ </td>
+ </ng-container>
+ <tr mat-header-row *matHeaderRowDef="['lastName','firstName' , 'email', 'segment', 'action']"></tr>
+ <tr mat-row *matRowDef="let row; columns: ['lastName', 'firstName', 'email', 'segment', 'action']"></tr>
@@ -40 +51 @@
- <div class="customer-form-container">
+ <div class="customer-form-container" *ngIf="selectedCustomer">
diff --git a/src/app/pages/customer-management/customer-management.component.ts b/src/app/pages/customer-management/customer-management.component.ts
index 558c49d..c53315b 100644
--- a/src/app/pages/customer-management/customer-management.component.ts
+++ b/src/app/pages/customer-management/customer-management.component.ts
@@ -6 +6 @@ import { MatDialog } from '@angular/material/dialog';
-import { CustomerDetailsDialog } from '../../dialogs/customer-details/customer-details.dialog';
+import { CustomerDetailsDialogComponent } from '../../dialogs/customer-details-dialog/customer-details-dialog.component';
@@ -15 +15 @@ export class CustomerManagementComponent implements OnInit {
- selectedCustomer: Customer;
+ selectedCustomer: Customer = {} as Customer;
@@ -26,0 +27 @@ export class CustomerManagementComponent implements OnInit {
+ this.selectedCustomer = customers[0] || {} as Customer;
@@ -37,3 +38,3 @@ export class CustomerManagementComponent implements OnInit {
- this.customerService.getCustomersBySegment(segment).subscribe(customers => {
- this.customers = customers;
- });
+ // this.customerService.getCustomersBySegment(segment).subscribe(customers => {
+ // this.customers = customers;
+ // });
@@ -43,2 +44,3 @@ export class CustomerManagementComponent implements OnInit {
- const dialogRef = this.dialog.open(CustomerDetailsDialog, {
- data: customer
+ const dialogRef = this.dialog.open(CustomerDetailsDialogComponent, {
+ width: '600px',
+ data: { customer }
diff --git a/src/app/pages/dashboard/dashboard.component.html b/src/app/pages/dashboard/dashboard.component.html
index afd0078..be01954 100644
--- a/src/app/pages/dashboard/dashboard.component.html
+++ b/src/app/pages/dashboard/dashboard.component.html
@@ -1,3 +0,0 @@
-<app-header [user]="user"></app-header>
-<app-side-menu></app-side-menu>
-
@@ -6 +3 @@
- <mat-card-title>ダッシュボード</mat-card-title>
+ <mat-card-title class="dashboard-card-title">ダッシュボード</mat-card-title>
@@ -9 +6 @@
- <mat-card-content>
+ <mat-card-content class="dashboard-card-content">
@@ -12 +9 @@
- <div class="kpi-value">{{totalSalesAmount}}</div>
+ <div class="kpi-value">{{totalSalesAmount | currency:'JPY'}}</div>
@@ -26,2 +23,2 @@
- <h3>最近のアクティビティ</h3>
- <table>
+ <h3 class="recent-activities-section-title">最近のアクティビティ</h3>
+ <table class="recent-activities-table">
@@ -30,4 +27,4 @@
- <th>日付</th>
- <th>タイトル</th>
- <th>種類</th>
- <th>ステータス</th>
+ <th class="recent-activities-table-header">日付</th>
+ <th class="recent-activities-table-header">タイトル</th>
+ <th class="recent-activities-table-header">種類</th>
+ <th class="recent-activities-table-header">ステータス</th>
@@ -38,4 +35,4 @@
- <td>{{activity.date | date: 'yyyy/MM/dd'}}</td>
- <td>{{activity.title}}</td>
- <td>{{activity.type}}</td>
- <td>{{activity.status}}</td>
+ <td class="recent-activities-table-cell">{{activity.date | date: 'yyyy/MM/dd'}}</td>
+ <td class="recent-activities-table-cell">{{activity.title}}</td>
+ <td class="recent-activities-table-cell">{{activity.type}}</td>
+ <td class="recent-activities-table-cell">{{activity.status}}</td>
@@ -48,2 +45,2 @@
- <h3>今後のタスク</h3>
- <table>
+ <h3 class="upcoming-tasks-section-title">今後のタスク</h3>
+ <table class="upcoming-tasks-table">
@@ -52,3 +49,3 @@
- <th>期限</th>
- <th>タイトル</th>
- <th>ステータス</th>
+ <th class="upcoming-tasks-table-header">期限</th>
+ <th class="upcoming-tasks-table-header">タイトル</th>
+ <th class="upcoming-tasks-table-header">ステータス</th>
@@ -59,3 +56,3 @@
- <td>{{task.endDate | date: 'yyyy/MM/dd'}}</td>
- <td>{{task.title}}</td>
- <td>{{task.status}}</td>
+ <td class="upcoming-tasks-table-cell">{{task.endDate | date: 'yyyy/MM/dd'}}</td>
+ <td class="upcoming-tasks-table-cell">{{task.title}}</td>
+ <td class="upcoming-tasks-table-cell">{{task.status}}</td>
diff --git a/src/app/pages/dashboard/dashboard.component.scss b/src/app/pages/dashboard/dashboard.component.scss
index e69de29..ddfb350 100644
--- a/src/app/pages/dashboard/dashboard.component.scss
+++ b/src/app/pages/dashboard/dashboard.component.scss
@@ -0,0 +1,63 @@
+.dashboard-card {
+ margin: 0 auto;
+ padding: 24px;
+ border-radius: 12px;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.kpi-section {
+ width: 500px;
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 24px;
+}
+
+.kpi-item {
+ text-align: center;
+}
+
+.kpi-value {
+ font-size: 36px;
+ font-weight: bold;
+ color: #1976d2;
+ margin-bottom: 8px;
+}
+
+.kpi-label {
+ font-size: 14px;
+ color: #666;
+}
+
+.recent-activities-section {
+ margin-bottom: 24px;
+}
+
+.recent-activities-section h3 {
+ font-size: 20px;
+ margin-bottom: 16px;
+}
+
+table {
+ width: 100%;
+ border-collapse: collapse;
+ border-spacing: 0;
+ font-size: 14px;
+}
+
+thead {
+ background-color: #f5f5f5;
+}
+
+th {
+ font-weight: normal;
+ text-align: left;
+ padding: 12px 16px;
+ border-bottom: 1px solid #ddd;
+}
+
+td {
+ text-align: left;
+ padding: 12px 16px;
+ border-bottom: 1px solid #ddd;
+}
+
diff --git a/src/app/pages/dashboard/dashboard.component.ts b/src/app/pages/dashboard/dashboard.component.ts
index 3666c29..be7cb35 100644
--- a/src/app/pages/dashboard/dashboard.component.ts
+++ b/src/app/pages/dashboard/dashboard.component.ts
@@ -3,2 +3,2 @@ import { Component, OnInit } from '@angular/core';
-import { User, Sale, SalesGoal, Task, Claim } from '../../models';
-import { SalesService, TaskService, ClaimsService } from '../../services';
+import { User, Sale, SalesGoal, Task, Claim, UserRole } from '../../models';
+import { SalesService, TaskService, ClaimsService, PerformanceService } from '../../services';
@@ -16,2 +16,2 @@ export class DashboardComponent implements OnInit {
- recentActivities: { date: Date, title: string, type: string, status: string }[];
- upcomingTasks: { endDate: Date, title: string, status: string }[];
+ recentActivities: { date: Date, title: string, type: string, status: string }[] = [];
+ upcomingTasks: { endDate: Date, title: string, status: string }[] = [];
@@ -19 +19 @@ export class DashboardComponent implements OnInit {
- constructor(private salesService: SalesService, private taskService: TaskService, private claimsService: ClaimsService) {
+ constructor(private salesService: SalesService, private taskService: TaskService, private claimsService: ClaimsService, private performanceService: PerformanceService) {
@@ -23 +23 @@ export class DashboardComponent implements OnInit {
- this.user = { id: 1, username: 'johndoe', password: 'password', email: 'johndoe@example.com', firstName: 'John', lastName: 'Doe', role: 'EMPLOYEE', profileImage: 'https://via.placeholder.com/150' };
+ this.user = { id: 1, username: 'johndoe', password: 'password', email: 'johndoe@example.com', firstName: 'John', lastName: 'Doe', role: UserRole.EMPLOYEE, profileImage: 'https://via.placeholder.com/150' };
@@ -30 +30 @@ export class DashboardComponent implements OnInit {
- this.salesService.getKpis().subscribe((kpis) => {
+ this.performanceService.getKpis().subscribe((kpis) => {
diff --git a/src/app/pages/login/login.component.html b/src/app/pages/login/login.component.html
index 1cafab4..66f27b9 100644
--- a/src/app/pages/login/login.component.html
+++ b/src/app/pages/login/login.component.html
@@ -3 +3 @@
- <form class="login-form" #loginForm="ngForm" (ngSubmit)="onSubmit()">
+ <form class="login-form" #loginForm="ngForm" (ngSubmit)="onSubmit(loginForm)">
@@ -7 +7 @@
- <mat-error *ngIf="loginForm.controls['username'].invalid && (loginForm.controls['username'].dirty || loginForm.controls['username'].touched)">
+ <mat-error *ngIf="loginForm.controls['username']?.invalid && (loginForm.controls['username']?.dirty || loginForm.controls['username']?.touched)">
@@ -14 +14 @@
- <mat-error *ngIf="loginForm.controls['password'].invalid && (loginForm.controls['password'].dirty || loginForm.controls['password'].touched)">
+ <mat-error *ngIf="loginForm.controls['password']?.invalid && (loginForm.controls['password']?.dirty || loginForm.controls['password']?.touched)">
diff --git a/src/app/pages/login/login.component.scss b/src/app/pages/login/login.component.scss
index e69de29..a6b5a8b 100644
--- a/src/app/pages/login/login.component.scss
+++ b/src/app/pages/login/login.component.scss
@@ -0,0 +1,37 @@
+.login-container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 32px;
+ background-color: #fff;
+ box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
+ border-radius: 8px;
+ width: 400px;
+ margin: auto;
+ margin-top: 64px;
+}
+
+.login-title {
+ font-size: 32px;
+ margin-bottom: 24px;
+}
+
+.login-form {
+ width: 100%;
+}
+
+.login-input {
+ width: 100%;
+ margin-bottom: 16px;
+}
+
+.login-button {
+ width: 100%;
+ margin-top: 24px;
+}
+
+.forgot-password-link {
+ margin-top: 16px;
+ color: #3f51b5;
+ cursor: pointer;
+}
\ No newline at end of file
diff --git a/src/app/pages/login/login.component.ts b/src/app/pages/login/login.component.ts
index 279fe93..4c173d0 100644
--- a/src/app/pages/login/login.component.ts
+++ b/src/app/pages/login/login.component.ts
@@ -5 +5 @@ import { MatDialog } from '@angular/material/dialog';
-import { ForgotPasswordDialog } from '../../dialogs/forgot-password-dialog.component';
+import { ForgotPasswordDialogComponent } from '../../dialogs/forgot-password-dialog/forgot-password-dialog.component';
@@ -7,0 +8 @@ import { AuthService } from '../../services';
+import { Router } from '@angular/router';
@@ -19 +20 @@ export class LoginComponent implements OnInit {
- constructor(private authService: AuthService, private dialog: MatDialog) {
+ constructor(private authService: AuthService, private router: Router, private dialog: MatDialog) {
@@ -29,0 +31 @@ export class LoginComponent implements OnInit {
+ this.router.navigate(['/dashboard']);
@@ -36 +38 @@ export class LoginComponent implements OnInit {
- if (loginForm.controls.username.invalid) {
+ if (loginForm.controls['username'].invalid) {
@@ -38 +40 @@ export class LoginComponent implements OnInit {
- } else if (loginForm.controls.password.invalid) {
+ } else if (loginForm.controls['password'].invalid) {
@@ -45 +47 @@ export class LoginComponent implements OnInit {
- const dialogRef = this.dialog.open(ForgotPasswordDialog, {
+ const dialogRef = this.dialog.open(ForgotPasswordDialogComponent, {
@@ -52,0 +55 @@ export class LoginComponent implements OnInit {
+ this.authService.forgotPassword(result.email).subscribe();
diff --git a/src/app/pages/performance-reporting/performance-reporting.component.html b/src/app/pages/performance-reporting/performance-reporting.component.html
index c3dfb8a..ecc8401 100644
--- a/src/app/pages/performance-reporting/performance-reporting.component.html
+++ b/src/app/pages/performance-reporting/performance-reporting.component.html
@@ -27 +27 @@
- [colors]="lineChartColors" [legend]="lineChartLegend" [chartType]="lineChartType"></canvas>
+ [legend]="lineChartLegend" [type]="lineChartType"></canvas>
diff --git a/src/app/pages/performance-reporting/performance-reporting.component.ts b/src/app/pages/performance-reporting/performance-reporting.component.ts
index a5898f2..1266ff3 100644
--- a/src/app/pages/performance-reporting/performance-reporting.component.ts
+++ b/src/app/pages/performance-reporting/performance-reporting.component.ts
@@ -4,0 +5 @@ import { PerformanceService } from '../../services';
+import { ChartType, Plugin } from 'chart.js';
@@ -12,8 +13,8 @@ export class PerformanceReportingComponent implements OnInit {
- salesData: SalesData[];
- kpis: Kpi[];
- lineChartData: any[];
- lineChartLabels: string[];
- lineChartOptions: any;
- lineChartColors: any[];
- lineChartLegend: boolean;
- lineChartType: string;
+ salesData: SalesData[] = [];
+ kpis: Kpi[] = [];
+ lineChartData: any[] = [];
+ lineChartLabels: string[] = [];
+ lineChartOptions: any = {};
+ lineChartColors: any[] = [];
+ lineChartLegend: boolean = false;
+ lineChartType: ChartType;
@@ -32,4 +33,7 @@ export class PerformanceReportingComponent implements OnInit {
- xAxes: [{
- ticks: {
- callback: function (value: any) {
- return new Date(value).toLocaleDateString();
+ x: {
+ type: 'time', // 時間軸として扱う場合
+ time: {
+ unit: 'day', // ラベルとして日単位で表示する場合
+ displayFormats: {
+ day: 'YYYY/MM/DD' // ラベルのフォーマットを指定する場合
+ }
@@ -38 +41,0 @@ export class PerformanceReportingComponent implements OnInit {
- }]
diff --git a/src/app/pages/reference-management/reference-management.component.html b/src/app/pages/reference-management/reference-management.component.html
index a62b2ae..922a758 100644
--- a/src/app/pages/reference-management/reference-management.component.html
+++ b/src/app/pages/reference-management/reference-management.component.html
@@ -8,4 +7,0 @@
- <ng-container matColumnDef="firstName">
- <mat-header-cell *matHeaderCellDef>名</mat-header-cell>
- <mat-cell *matCellDef="let referral">{{ referral.firstName }}</mat-cell>
- </ng-container>
@@ -14 +10,5 @@
- <mat-cell *matCellDef="let referral">{{ referral.lastName }}</mat-cell>
+ <mat-cell *matCellDef="let referral">{{ customerMap[referral.customerId]?.lastName }}</mat-cell>
+ </ng-container>
+ <ng-container matColumnDef="firstName">
+ <mat-header-cell *matHeaderCellDef>名</mat-header-cell>
+ <mat-cell *matCellDef="let referral">{{ customerMap[referral.customerId]?.firstName }}</mat-cell>
@@ -18 +18 @@
- <mat-cell *matCellDef="let referral">{{ referral.email }}</mat-cell>
+ <mat-cell *matCellDef="let referral">{{ customerMap[referral.customerId]?.email }}</mat-cell>
@@ -22 +22 @@
- <mat-cell *matCellDef="let referral">{{ referral.phone }}</mat-cell>
+ <mat-cell *matCellDef="let referral">{{ customerMap[referral.customerId]?.phone }}</mat-cell>
@@ -53 +53 @@
- <app-referral-form [referral]="selectedReferral" (referralChange)="onReferralChange($event)"></app-referral-form>
+ <!-- <app-referral-form [referral]="selectedReferral" (referralChange)="onReferralChange($event)"></app-referral-form> -->
diff --git a/src/app/pages/reference-management/reference-management.component.ts b/src/app/pages/reference-management/reference-management.component.ts
index 865297e..072eb37 100644
--- a/src/app/pages/reference-management/reference-management.component.ts
+++ b/src/app/pages/reference-management/reference-management.component.ts
@@ -3,2 +3,2 @@ import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
-import { Referral, ReferralStatus } from '../../models';
-import { ReferenceService } from '../../services';
+import { Customer, Referral, ReferralStatus } from '../../models';
+import { CustomerService, ReferenceService } from '../../services';
@@ -15 +15 @@ export class ReferenceManagementComponent implements OnInit {
- displayedColumns: string[] = ['firstName', 'lastName', 'email', 'phone', 'referralDate', 'status', 'actions'];
+ displayedColumns: string[] = ['lastName', 'firstName', 'email', 'phone', 'referralDate', 'status', 'actions'];
@@ -21 +21,3 @@ export class ReferenceManagementComponent implements OnInit {
- constructor(private referenceService: ReferenceService, private dialog: MatDialog) {
+ customerMap: { [id: number]: Customer } = {};
+
+ constructor(private referenceService: ReferenceService, private customerService: CustomerService, private dialog: MatDialog) {
@@ -24,0 +27,6 @@ export class ReferenceManagementComponent implements OnInit {
+ this.customerService.getCustomers().subscribe(customers => {
+ this.customerMap = customers.reduce((map: { [id: number]: Customer }, customer: Customer) => {
+ map[customer.id] = customer;
+ return map;
+ }, this.customerMap);
+ });
@@ -35,0 +44 @@ export class ReferenceManagementComponent implements OnInit {
+ width: '600px',
@@ -62,6 +71,2 @@ export class ReferenceManagementComponent implements OnInit {
-
- deleteReferral(referral: Referral): void {
- this.referenceService.deleteReferral(referral.id).subscribe(() => {
- const index = this.referrals.findIndex(r => r.id === referral.id);
- this.referrals.splice(index, 1);
- });
+ closeDialog(): void {
+ this.dialog.closeAll();
@@ -68,0 +74,9 @@ export class ReferenceManagementComponent implements OnInit {
+
+ // TODO
+ // deleteReferral(referral: Referral): void {
+ // this.referenceService.deleteReferral(referral.id).subscribe(() => {
+ // const index = this.referrals.findIndex(r => r.id === referral.id);
+ // this.referrals.splice(index, 1);
+ // });
+ // }
+
diff --git a/src/app/pages/sales-literature-management/sales-literature-management.component.ts b/src/app/pages/sales-literature-management/sales-literature-management.component.ts
index 67d922f..e8ce53b 100644
--- a/src/app/pages/sales-literature-management/sales-literature-management.component.ts
+++ b/src/app/pages/sales-literature-management/sales-literature-management.component.ts
@@ -31 +31 @@ export class SalesLiteratureManagementComponent implements OnInit {
- openUploadDialog(): void {
+ openUploadDialog(literature: SalesLiterature = null): void {
@@ -34 +34 @@ export class SalesLiteratureManagementComponent implements OnInit {
- data: {}
+ data: { literature }
@@ -55,3 +55,3 @@ export class SalesLiteratureManagementComponent implements OnInit {
- this.salesLiteratureService.deleteLiterature(literature.id).subscribe(() => {
- this.literatures = this.literatures.filter(l => l.id !== literature.id);
- });
+ // this.salesLiteratureService.deleteLiterature(literature.id).subscribe(() => {
+ // this.literatures = this.literatures.filter(l => l.id !== literature.id);
+ // });
diff --git a/src/app/pages/sales-management/sales-management.component.html b/src/app/pages/sales-management/sales-management.component.html
index e65b0fe..7aee8a8 100644
--- a/src/app/pages/sales-management/sales-management.component.html
+++ b/src/app/pages/sales-management/sales-management.component.html
@@ -7 +7 @@
- <mat-cell *matCellDef="let sale">{{ sale.customerName }}</mat-cell>
+ <mat-cell *matCellDef="let sale">{{ customerMap[sale.customerId]?.lastName }}</mat-cell>
diff --git a/src/app/pages/sales-management/sales-management.component.ts b/src/app/pages/sales-management/sales-management.component.ts
index dd69577..39d5f13 100644
--- a/src/app/pages/sales-management/sales-management.component.ts
+++ b/src/app/pages/sales-management/sales-management.component.ts
@@ -3,2 +3,2 @@ import { Component, OnInit, ViewChild } from '@angular/core';
-import { Sale, SalesGoal } from '../../models';
-import { SalesService } from '../../services';
+import { Customer, Sale, SalesGoal } from '../../models';
+import { CustomerService, SalesService } from '../../services';
@@ -15 +15 @@ export class SalesManagementComponent implements OnInit {
- salesGoal: SalesGoal = { targetAmount: 0, startDate: new Date(), endDate: new Date(), progress: 0 };
+ salesGoal: SalesGoal = { id: -1, userId: -1, targetAmount: 0, startDate: new Date(), endDate: new Date(), progress: 0 };
@@ -20 +20,4 @@ export class SalesManagementComponent implements OnInit {
- constructor(private salesService: SalesService, private snackBar: MatSnackBar) {
+ customers: Customer[] = [];
+ customerMap: { [id: number]: Customer } = {};
+
+ constructor(private salesService: SalesService, private customerService: CustomerService, private snackBar: MatSnackBar) {
@@ -23,0 +27,9 @@ export class SalesManagementComponent implements OnInit {
+ this.customerService.getCustomers().subscribe(
+ (customers: Customer[]) => {
+ this.customers = customers;
+ this.customerMap = customers.reduce((map: { [id: number]: Customer }, customer: Customer) => {
+ map[customer.id] = customer;
+ return map;
+ }, this.customerMap);
+ }
+ );
@@ -51,0 +64,2 @@ export class SalesManagementComponent implements OnInit {
+ id: this.salesGoal.id,
+ userId: this.salesGoal.userId,
diff --git a/src/app/pages/task-management/task-management.component.ts b/src/app/pages/task-management/task-management.component.ts
index 3918bfd..de6961d 100644
--- a/src/app/pages/task-management/task-management.component.ts
+++ b/src/app/pages/task-management/task-management.component.ts
@@ -3 +3 @@ import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
-import { MatDialog } from '@angular/material/dialog';
+import { MatDialog, MatDialogRef } from '@angular/material/dialog';
@@ -15 +15 @@ export class TaskManagementComponent implements OnInit {
- selectedTask: Task;
+ selectedTask: Task = { id: 0, userId: 0, description: '', endDate: new Date(), reminder: null as Reminder, startDate: new Date(), status: TaskStatus.NOT_STARTED, title: '' } as Task;
@@ -16,0 +17 @@ export class TaskManagementComponent implements OnInit {
+ @ViewChild('taskDetailsDialogTemplate')
@@ -18,0 +20,2 @@ export class TaskManagementComponent implements OnInit {
+ dialogRef: MatDialogRef<any>;
+
@@ -28 +31 @@ export class TaskManagementComponent implements OnInit {
- const dialogRef = this.dialog.open(this.taskDetailsDialogTemplate, {
+ this.dialogRef = this.dialog.open(this.taskDetailsDialogTemplate, {
@@ -33,2 +36,2 @@ export class TaskManagementComponent implements OnInit {
- dialogRef.afterClosed().subscribe(result => {
- this.selectedTask = null;
+ this.dialogRef.afterClosed().subscribe(result => {
+ // this.selectedTask = {} as Task;
@@ -52 +55 @@ export class TaskManagementComponent implements OnInit {
- this.selectedTask = null;
+ this.selectedTask = {} as Task;
@@ -56 +59,2 @@ export class TaskManagementComponent implements OnInit {
- this.selectedTask = null;
+ this.dialogRef.close();
+ // this.selectedTask = {} as Task;
@@ -65,48 +69,48 @@ export class TaskManagementComponent implements OnInit {
-//
-// <!-- src/app/pages/task-management.component.html -->
-<div class="task-management-container">
- <div class="task-list-container">
- <mat-card>
- <mat-table [dataSource]="tasks">
- <ng-container matColumnDef="title">
- <mat-header-cell *matHeaderCellDef>Title</mat-header-cell>
- <mat-cell *matCellDef="let task">{{ task.title }}</mat-cell>
- </ng-container>
- <ng-container matColumnDef="description">
- <mat-header-cell *matHeaderCellDef>Description</mat-header-cell>
- <mat-cell *matCellDef="let task">{{ task.description }}</mat-cell>
- </ng-container>
- <ng-container matColumnDef="startDate">
- <mat-header-cell *matHeaderCellDef>Start Date</mat-header-cell>
- <mat-cell *matCellDef="let task">{{ task.startDate | date }}</mat-cell>
- </ng-container>
- <ng-container matColumnDef="endDate">
- <mat-header-cell *matHeaderCellDef>End Date</mat-header-cell>
- <mat-cell *matCellDef="let task">{{ task.endDate | date }}</mat-cell>
- </ng-container>
- <ng-container matColumnDef="status">
- <mat-header-cell *matHeaderCellDef>Status</mat-header-cell>
- <mat-cell *matCellDef="let task">{{ task.status }}</mat-cell>
- </ng-container>
- <ng-container matColumnDef="actions">
- <mat-header-cell *matHeaderCellDef>Actions</mat-header-cell>
- <mat-cell *matCellDef="let task">
- <button mat-icon-button color="primary" (click)="editTask(task)">
- <mat-icon>edit</mat-icon>
- </button>
- <button mat-icon-button color="primary" (click)="openTaskDetailsDialog(task)">
- <mat-icon>info</mat-icon>
- </button>
- </mat-cell>
- </ng-container>
- <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
- <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
- </mat-table>
- </mat-card>
- </div>
- <div class="task-form-container">
- <mat-card>
- <app-task-form [task]="selectedTask" (taskChange)="onTaskChange($event)"></app-task-form>
- </mat-card>
- </div>
-</div>
+// //
+// // <!-- src/app/pages/task-management.component.html -->
+// <div class="task-management-container">
+// <div class="task-list-container">
+// <mat-card>
+// <mat-table [dataSource]="tasks">
+// <ng-container matColumnDef="title">
+// <mat-header-cell *matHeaderCellDef>Title</mat-header-cell>
+// <mat-cell *matCellDef="let task">{{ task.title }}</mat-cell>
+// </ng-container>
+// <ng-container matColumnDef="description">
+// <mat-header-cell *matHeaderCellDef>Description</mat-header-cell>
+// <mat-cell *matCellDef="let task">{{ task.description }}</mat-cell>
+// </ng-container>
+// <ng-container matColumnDef="startDate">
+// <mat-header-cell *matHeaderCellDef>Start Date</mat-header-cell>
+// <mat-cell *matCellDef="let task">{{ task.startDate | date }}</mat-cell>
+// </ng-container>
+// <ng-container matColumnDef="endDate">
+// <mat-header-cell *matHeaderCellDef>End Date</mat-header-cell>
+// <mat-cell *matCellDef="let task">{{ task.endDate | date }}</mat-cell>
+// </ng-container>
+// <ng-container matColumnDef="status">
+// <mat-header-cell *matHeaderCellDef>Status</mat-header-cell>
+// <mat-cell *matCellDef="let task">{{ task.status }}</mat-cell>
+// </ng-container>
+// <ng-container matColumnDef="actions">
+// <mat-header-cell *matHeaderCellDef>Actions</mat-header-cell>
+// <mat-cell *matCellDef="let task">
+// <button mat-icon-button color="primary" (click)="editTask(task)">
+// <mat-icon>edit</mat-icon>
+// </button>
+// <button mat-icon-button color="primary" (click)="openTaskDetailsDialog(task)">
+// <mat-icon>info</mat-icon>
+// </button>
+// </mat-cell>
+// </ng-container>
+// <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
+// <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
+// </mat-table>
+// </mat-card>
+// </div>
+// <div class="task-form-container">
+// <mat-card>
+// <app-task-form [task]="selectedTask" (taskChange)="onTaskChange($event)"></app-task-form>
+// </mat-card>
+// </div>
+// </div>
@@ -114,14 +118,14 @@ export class TaskManagementComponent implements OnInit {
-<ng-template #taskDetailsDialog let-data>
- <h2 mat-dialog-title>Task Details</h2>
- <mat-dialog-content>
- <p><strong>Title:</strong> {{ data.task.title }}</p>
- <p><strong>Description:</strong> {{ data.task.description }}</p>
- <p><strong>Start Date:</strong> {{ data.task.startDate | date }}</p>
- <p><strong>End Date:</strong> {{ data.task.endDate | date }}</p>
- <p><strong>Status:</strong> {{ data.task.status }}</p>
- <p><strong>Reminder:</strong> {{ data.task.reminder?.message }}</p>
- </mat-dialog-content>
- <mat-dialog-actions>
- <button mat-button (click)="closeDialog()">Close</button>
- </mat-dialog-actions>
-</ng-template>
\ No newline at end of file
+// <ng-template #taskDetailsDialog let-data>
+// <h2 mat-dialog-title>Task Details</h2>
+// <mat-dialog-content>
+// <p><strong>Title:</strong> {{ data.task.title }}</p>
+// <p><strong>Description:</strong> {{ data.task.description }}</p>
+// <p><strong>Start Date:</strong> {{ data.task.startDate | date }}</p>
+// <p><strong>End Date:</strong> {{ data.task.endDate | date }}</p>
+// <p><strong>Status:</strong> {{ data.task.status }}</p>
+// <p><strong>Reminder:</strong> {{ data.task.reminder?.message }}</p>
+// </mat-dialog-content>
+// <mat-dialog-actions>
+// <button mat-button (click)="closeDialog()">Close</button>
+// </mat-dialog-actions>
+// </ng-template>
\ No newline at end of file
diff --git a/src/app/pages/team-collaboration/team-collaboration.component.html b/src/app/pages/team-collaboration/team-collaboration.component.html
index 847588e..a888042 100644
--- a/src/app/pages/team-collaboration/team-collaboration.component.html
+++ b/src/app/pages/team-collaboration/team-collaboration.component.html
@@ -19 +19 @@
- <td mat-cell *matCellDef="let member"> {{member.firstName}} {{member.lastName}} </td>
+ <td mat-cell *matCellDef="let member"> {{member.lastName}} {{member.firstName}}</td>
diff --git a/src/app/pages/team-collaboration/team-collaboration.component.ts b/src/app/pages/team-collaboration/team-collaboration.component.ts
index 9ae1e11..80a1d51 100644
--- a/src/app/pages/team-collaboration/team-collaboration.component.ts
+++ b/src/app/pages/team-collaboration/team-collaboration.component.ts
@@ -4,2 +4,2 @@ import { User, SharedInformation, InfoCategory } from '../../models';
-import { CollaborationService } from '../../services';
-import { MatDialog } from '@angular/material/dialog';
+import { CollaborationService, UserService } from '../../services';
+import { MatDialog, MatDialogRef } from '@angular/material/dialog';
@@ -20 +20 @@ export class TeamCollaborationComponent implements OnInit {
- constructor(private collaborationService: CollaborationService, private dialog: MatDialog, private fb: FormBuilder) {
+ constructor(private collaborationService: CollaborationService, private userService: UserService, private dialog: MatDialog, private fb: FormBuilder) {
@@ -35 +35 @@ export class TeamCollaborationComponent implements OnInit {
- this.collaborationService.getTeamMembers().subscribe((teamMembers: User[]) => {
+ this.userService.getTeamMembers().subscribe((teamMembers: User[]) => {
@@ -61,3 +61,3 @@ export class TeamCollaborationComponent implements OnInit {
- this.collaborationService.searchTeamMembers(query).subscribe((teamMembers: User[]) => {
- this.teamMembers = teamMembers;
- });
+ // this.collaborationService.searchTeamMembers(query).subscribe((teamMembers: User[]) => {
+ // this.teamMembers = teamMembers;
+ // });
@@ -65 +65 @@ export class TeamCollaborationComponent implements OnInit {
- this.collaborationService.getTeamMembers().subscribe((teamMembers: User[]) => {
+ this.userService.getTeamMembers().subscribe((teamMembers: User[]) => {
@@ -74,3 +74,3 @@ export class TeamCollaborationComponent implements OnInit {
- this.collaborationService.searchSharedInformation(query).subscribe((sharedInfo: SharedInformation[]) => {
- this.sharedInfo = sharedInfo;
- });
+ // this.collaborationService.searchSharedInformation(query).subscribe((sharedInfo: SharedInformation[]) => {
+ // this.sharedInfo = sharedInfo;
+ // });
@@ -118 +118 @@ export class AddSharedInfoDialogComponent {
- constructor(private fb: FormBuilder) {
+ constructor(private fb: FormBuilder, private dialog: MatDialogRef<any>) {
diff --git a/src/app/pages/training-management/training-management.component.html b/src/app/pages/training-management/training-management.component.html
index 96b26f8..47a9d0a 100644
--- a/src/app/pages/training-management/training-management.component.html
+++ b/src/app/pages/training-management/training-management.component.html
@@ -48 +48 @@
- <div class="skill-acquisition-status">
+ <div class="skill-acquisition-status" *ngIf="selectedTraining.id">
@@ -50 +50 @@
- <mat-progress-bar mode="determinate" [value]="skillAcquisitionStatus"></mat-progress-bar>
+ <mat-progress-bar mode="determinate" [value]="skillAcquisitionStatus*20" style="height: 24px;"></mat-progress-bar>
@@ -52 +52 @@
- <button mat-raised-button color="primary" (click)="onParticipateClick()">参加する</button>
+ <button *ngIf="selectedTraining.id" mat-raised-button color="primary" (click)="onParticipateClick()" style="margin-top: 20px;">参加する</button>
diff --git a/src/app/pages/training-management/training-management.component.ts b/src/app/pages/training-management/training-management.component.ts
index 98ed66f..d6316d4 100644
--- a/src/app/pages/training-management/training-management.component.ts
+++ b/src/app/pages/training-management/training-management.component.ts
@@ -3 +3 @@ import { Component, OnInit } from '@angular/core';
-import { Training, TrainingEffectiveness } from '../../models';
+import { Training, TrainingEffectiveness, TrainingStatus } from '../../models';
@@ -14 +14 @@ export class TrainingManagementComponent implements OnInit {
- selectedTraining: Training;
+ selectedTraining: Training = {} as Training;
@@ -22,0 +23,2 @@ export class TrainingManagementComponent implements OnInit {
+
+ // TODO 要検証:historyで全量が取れていて、ここで振り分けるという情報がここまで伝わっていない?
@@ -24 +26,9 @@ export class TrainingManagementComponent implements OnInit {
- this.trainings = trainings;
+ this.trainings = [];
+ this.upcomingTrainings = [];
+ trainings.forEach(training => {
+ if (training.status === TrainingStatus.COMPLETED) {
+ this.trainings.push(training);
+ } else if (training.status === TrainingStatus.UPCOMING) {
+ this.upcomingTrainings.push(training);
+ }
+ });
@@ -30,8 +39,0 @@ export class TrainingManagementComponent implements OnInit {
-
- this.trainingService.getUpcomingTrainings().subscribe(trainings => {
- this.upcomingTrainings = trainings;
- if (trainings.length > 0) {
- this.selectedTraining = trainings[0];
- this.onTrainingChange();
- }
- });
@@ -46,2 +48,6 @@ export class TrainingManagementComponent implements OnInit {
- this.trainingService.getTrainingEffectiveness(this.selectedTraining.id).subscribe(eff => {
- this.skillAcquisitionStatus = eff.effectivenessScore;
+ console.log(this.selectedTraining.id);
+ this.trainingService.getTrainingEffectiveness().subscribe(eff => {
+ const scoreObj = eff.find(e => e.trainingId === this.selectedTraining.id);
+ if (scoreObj) {
+ this.skillAcquisitionStatus = scoreObj.effectivenessScore;
+ } else { }
@@ -57,48 +63,48 @@ export class TrainingManagementComponent implements OnInit {
-//
-// <!-- src/app/pages/training-management.component.html -->
-<div class="training-management-container">
- <div class="training-history">
- <mat-card>
- <mat-card-title>Training History</mat-card-title>
- <mat-table [dataSource]="trainings">
- <ng-container matColumnDef="title">
- <mat-header-cell *matHeaderCellDef>Title</mat-header-cell>
- <mat-cell *matCellDef="let row">{{row.title}}</mat-cell>
- </ng-container>
- <ng-container matColumnDef="description">
- <mat-header-cell *matHeaderCellDef>Description</mat-header-cell>
- <mat-cell *matCellDef="let row">{{row.description}}</mat-cell>
- </ng-container>
- <ng-container matColumnDef="startDate">
- <mat-header-cell *matHeaderCellDef>Start Date</mat-header-cell>
- <mat-cell *matCellDef="let row">{{row.startDate | date}}</mat-cell>
- </ng-container>
- <ng-container matColumnDef="endDate">
- <mat-header-cell *matHeaderCellDef>End Date</mat-header-cell>
- <mat-cell *matCellDef="let row">{{row.endDate | date}}</mat-cell>
- </ng-container>
- <ng-container matColumnDef="status">
- <mat-header-cell *matHeaderCellDef>Status</mat-header-cell>
- <mat-cell *matCellDef="let row">{{row.status}}</mat-cell>
- </ng-container>
- <mat-header-row *matHeaderRowDef="matColumnDef"></mat-header-row>
- <mat-row *matRowDef="let row; columns: matColumnDef;" (click)="onTrainingClick(row)"></mat-row>
- </mat-table>
- <div *ngIf="trainings.length === 0">No completed training sessions found.</div>
- </mat-card>
- </div>
- <div class="training-participation">
- <mat-card>
- <mat-card-title>Training Participation</mat-card-title>
- <mat-form-field>
- <mat-label>Training Session</mat-label>
- <mat-select [(ngModel)]="selectedTraining" (ngModelChange)="onTrainingChange()">
- <mat-option *ngFor="let training of upcomingTrainings" [value]="training">{{training.title}}</mat-option>
- </mat-select>
- </mat-form-field>
- <mat-progress-bar mode="determinate" [value]="skillAcquisitionStatus"></mat-progress-bar>
- <button mat-raised-button color="primary" (click)="onParticipateClick()">Participate</button>
- <div *ngIf="upcomingTrainings.length === 0">No upcoming training sessions found.</div>
- </mat-card>
- </div>
-</div>
\ No newline at end of file
+// //
+// // <!-- src/app/pages/training-management.component.html -->
+// <div class="training-management-container">
+// <div class="training-history">
+// <mat-card>
+// <mat-card-title>Training History</mat-card-title>
+// <mat-table [dataSource]="trainings">
+// <ng-container matColumnDef="title">
+// <mat-header-cell *matHeaderCellDef>Title</mat-header-cell>
+// <mat-cell *matCellDef="let row">{{row.title}}</mat-cell>
+// </ng-container>
+// <ng-container matColumnDef="description">
+// <mat-header-cell *matHeaderCellDef>Description</mat-header-cell>
+// <mat-cell *matCellDef="let row">{{row.description}}</mat-cell>
+// </ng-container>
+// <ng-container matColumnDef="startDate">
+// <mat-header-cell *matHeaderCellDef>Start Date</mat-header-cell>
+// <mat-cell *matCellDef="let row">{{row.startDate | date}}</mat-cell>
+// </ng-container>
+// <ng-container matColumnDef="endDate">
+// <mat-header-cell *matHeaderCellDef>End Date</mat-header-cell>
+// <mat-cell *matCellDef="let row">{{row.endDate | date}}</mat-cell>
+// </ng-container>
+// <ng-container matColumnDef="status">
+// <mat-header-cell *matHeaderCellDef>Status</mat-header-cell>
+// <mat-cell *matCellDef="let row">{{row.status}}</mat-cell>
+// </ng-container>
+// <mat-header-row *matHeaderRowDef="matColumnDef"></mat-header-row>
+// <mat-row *matRowDef="let row; columns: matColumnDef;" (click)="onTrainingClick(row)"></mat-row>
+// </mat-table>
+// <div *ngIf="trainings.length === 0">No completed training sessions found.</div>
+// </mat-card>
+// </div>
+// <div class="training-participation">
+// <mat-card>
+// <mat-card-title>Training Participation</mat-card-title>
+// <mat-form-field>
+// <mat-label>Training Session</mat-label>
+// <mat-select [(ngModel)]="selectedTraining" (ngModelChange)="onTrainingChange()">
+// <mat-option *ngFor="let training of upcomingTrainings" [value]="training">{{training.title}}</mat-option>
+// </mat-select>
+// </mat-form-field>
+// <mat-progress-bar mode="determinate" [value]="skillAcquisitionStatus"></mat-progress-bar>
+// <button mat-raised-button color="primary" (click)="onParticipateClick()">Participate</button>
+// <div *ngIf="upcomingTrainings.length === 0">No upcoming training sessions found.</div>
+// </mat-card>
+// </div>
+// </div>
\ No newline at end of file
diff --git a/src/app/parts/claims-list/claims-list.component.html b/src/app/parts/claims-list/claims-list.component.html
index 4aef4e5..3021507 100644
--- a/src/app/parts/claims-list/claims-list.component.html
+++ b/src/app/parts/claims-list/claims-list.component.html
@@ -53 +53,2 @@
-<app-claim-details-dialog [claim]="selectedClaim" (claimChange)="onClaimChange($event)"></app-claim-details-dialog>
\ No newline at end of file
+<!-- TODO -->
+<!-- <app-claim-details-dialog [claim]="selectedClaim" (claimChange)="onClaimChange($event)"></app-claim-details-dialog> -->
\ No newline at end of file
diff --git a/src/app/parts/claims-list/claims-list.component.ts b/src/app/parts/claims-list/claims-list.component.ts
index 447f724..2b30747 100644
--- a/src/app/parts/claims-list/claims-list.component.ts
+++ b/src/app/parts/claims-list/claims-list.component.ts
@@ -6 +6 @@ import { MatDialog } from '@angular/material/dialog';
-import { ClaimDetailsDialogComponent } from '../../dialogs/claim-details-dialog.component';
+import { ClaimDetailsDialogComponent } from '../../dialogs/claim-details-dialog/claim-details-dialog.component';
@@ -40,8 +40,8 @@ export class ClaimsListComponent implements OnInit {
- this.claimsService.searchClaims(query).subscribe(
- (claims: Claim[]) => {
- this.claims = claims;
- },
- (error: any) => {
- console.error('Failed to retrieve claims. Please try again later.', error);
- }
- );
+ // this.claimsService.searchClaims(query).subscribe(
+ // (claims: Claim[]) => {
+ // this.claims = claims;
+ // },
+ // (error: any) => {
+ // console.error('Failed to retrieve claims. Please try again later.', error);
+ // }
+ // );
@@ -58 +58 @@ export class ClaimsListComponent implements OnInit {
- case 'customerName': return compare(a.customer.firstName + ' ' + a.customer.lastName, b.customer.firstName + ' ' + b.customer.lastName, isAsc);
+ case 'customerName': return compare(a.customerId, b.customerId, isAsc);
diff --git a/src/app/parts/customer-form/customer-form.component.html b/src/app/parts/customer-form/customer-form.component.html
index 611f289..1dd11ae 100644
--- a/src/app/parts/customer-form/customer-form.component.html
+++ b/src/app/parts/customer-form/customer-form.component.html
@@ -2 +2 @@
- <form (ngSubmit)="onSubmit()" #customerForm="ngForm">
+ <form (ngSubmit)="onSubmit(customerForm)" #customerForm="ngForm">
@@ -6 +6 @@
- <mat-error *ngIf="customerForm.controls['lastName'].invalid && customerForm.controls['lastName'].touched">
+ <mat-error *ngIf="customerForm.controls['lastName']?.invalid && customerForm.controls['lastName']?.touched">
@@ -13 +13 @@
- <mat-error *ngIf="customerForm.controls['firstName'].invalid && customerForm.controls['firstName'].touched">
+ <mat-error *ngIf="customerForm.controls['firstName']?.invalid && customerForm.controls['firstName']?.touched">
@@ -20 +20 @@
- <mat-error *ngIf="customerForm.controls['email'].invalid && customerForm.controls['email'].touched">
+ <mat-error *ngIf="customerForm.controls['email']?.invalid && customerForm.controls['email']?.touched">
@@ -27 +27 @@
- <mat-error *ngIf="customerForm.controls['phone'].invalid && customerForm.controls['phone'].touched">
+ <mat-error *ngIf="customerForm.controls['phone']?.invalid && customerForm.controls['phone']?.touched">
@@ -34 +34 @@
- <mat-error *ngIf="customerForm.controls['address'].invalid && customerForm.controls['address'].touched">
+ <mat-error *ngIf="customerForm.controls['address']?.invalid && customerForm.controls['address']?.touched">
diff --git a/src/app/parts/customer-form/customer-form.component.ts b/src/app/parts/customer-form/customer-form.component.ts
index 7415ffd..49c87f1 100644
--- a/src/app/parts/customer-form/customer-form.component.ts
+++ b/src/app/parts/customer-form/customer-form.component.ts
@@ -14 +14 @@ export class CustomerFormComponent implements OnInit {
- @Input() customer: Customer;
+ @Input() customer: Customer = {} as Customer;
diff --git a/src/app/parts/customer-list/customer-list.component.html b/src/app/parts/customer-list/customer-list.component.html
index d7b66db..4491409 100644
--- a/src/app/parts/customer-list/customer-list.component.html
+++ b/src/app/parts/customer-list/customer-list.component.html
@@ -37 +37,2 @@
- <app-customer-details-dialog [customer]="selectedCustomer" (close)="selectedCustomer = null"></app-customer-details-dialog>
+ <!-- TODO -->
+ <!-- <app-customer-details-dialog [customer]="selectedCustomer" (close)="selectedCustomer = null"></app-customer-details-dialog> -->
diff --git a/src/app/parts/customer-list/customer-list.component.ts b/src/app/parts/customer-list/customer-list.component.ts
index 360bd2a..bde6fe6 100644
--- a/src/app/parts/customer-list/customer-list.component.ts
+++ b/src/app/parts/customer-list/customer-list.component.ts
@@ -7 +7,2 @@ import { CustomerService } from '../../services';
-import { CustomerDetailsDialogComponent } from '../../dialogs/customer-details-dialog.component';
+import { CustomerDetailsDialogComponent } from '../../dialogs/customer-details-dialog/customer-details-dialog.component';
+import { MatDialog } from '@angular/material/dialog';
@@ -18 +19 @@ export class CustomerListComponent implements OnInit {
- @ViewChild(MatSort) sort: MatSort;
+ // @ViewChild(MatSort) sort: MatSort;
@@ -35 +36 @@ export class CustomerListComponent implements OnInit {
- constructor(private customerService: CustomerService) {
+ constructor(private customerService: CustomerService, private dialog: MatDialog) {
@@ -46 +47 @@ export class CustomerListComponent implements OnInit {
- const isAscending = this.sort.direction === 'asc';
+ const isAscending = this.sort['direction'] === 'asc';
@@ -67 +68,9 @@ export class CustomerListComponent implements OnInit {
- this.customerDetailsDialog.open(customer);
+ const dialogRef = this.dialog.open(CustomerDetailsDialogComponent, {
+ width: '400px',
+ data: customer
+ });
+
+ dialogRef.afterClosed().subscribe(result => {
+ if (result) {
+ }
+ });
diff --git a/src/app/parts/literature-upload/literature-upload.component.html b/src/app/parts/literature-upload/literature-upload.component.html
index 1d08a1f..0262e6d 100644
--- a/src/app/parts/literature-upload/literature-upload.component.html
+++ b/src/app/parts/literature-upload/literature-upload.component.html
@@ -0,0 +1 @@
+// html
@@ -7 +8 @@
- <mat-error *ngIf="literatureForm.controls['title'].invalid && literatureForm.controls['title'].touched">タイトルは必須です。</mat-error>
+ <mat-error *ngIf="literatureForm.controls['title']?.invalid && literatureForm.controls['title']?.touched">タイトルは必須です。</mat-error>
@@ -15,2 +16,3 @@
- <input matInput type="file" (change)="onFileSelected($event)" accept=".pdf,.docx,.xlsx,.pptx" required>
- <mat-error *ngIf="literatureForm.controls['file'].invalid && literatureForm.controls['file'].touched">ファイルは必須です。</mat-error>
+ <input matInput [value]="fileName" name="file" type="text" required readonly/>
+ <input type="file" (change)="onFileSelected($event)" accept=".pdf,.docx,.xlsx,.pptx" required #fileInput style="opacity: 0;">
+ <mat-error *ngIf="literatureForm.controls['file']?.invalid && literatureForm.controls['file']?.touched">ファイルは必須です。</mat-error>
diff --git a/src/app/parts/literature-upload/literature-upload.component.ts b/src/app/parts/literature-upload/literature-upload.component.ts
index ed5792d..ea19eba 100644
--- a/src/app/parts/literature-upload/literature-upload.component.ts
+++ b/src/app/parts/literature-upload/literature-upload.component.ts
@@ -1,2 +1 @@
-// src/app/parts/literature-upload.component.ts
-import { Component, OnInit, Output, EventEmitter, ViewChild } from '@angular/core';
+import { Component, OnInit, Output, EventEmitter, ViewChild, Inject } from '@angular/core';
@@ -5,0 +5 @@ import { SalesLiteratureService } from '../../services';
+import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
@@ -18,0 +19 @@ export class LiteratureUploadComponent implements OnInit {
+ fileName: string = '';
@@ -26,0 +28 @@ export class LiteratureUploadComponent implements OnInit {
+ @ViewChild('fileInput') fileInput: any;
@@ -28 +30,4 @@ export class LiteratureUploadComponent implements OnInit {
- constructor(private salesLiteratureService: SalesLiteratureService) {
+ constructor(private salesLiteratureService: SalesLiteratureService,
+ public dialogRef: MatDialogRef<LiteratureUploadComponent>,
+ @Inject(MAT_DIALOG_DATA) public data: { literature: SalesLiterature }
+ ) {
@@ -31,0 +37,4 @@ export class LiteratureUploadComponent implements OnInit {
+ if (this.data.literature) {
+ this.title = this.data.literature.title;
+ this.description = this.data.literature.description;
+ }
@@ -42 +51 @@ export class LiteratureUploadComponent implements OnInit {
- this.file.type
+ this.file.type as FileType
@@ -51,0 +61 @@ export class LiteratureUploadComponent implements OnInit {
+ this.fileName = this.file.name;
@@ -61,11 +71,12 @@ export class LiteratureUploadComponent implements OnInit {
- this.salesLiteratureService.uploadFile(uploadedLiterature.id, formData).subscribe(
- (response: any) => {
- uploadedLiterature.fileUrl = response.fileUrl;
- this.successMessage = 'File uploaded successfully.';
- this.literatureChange.emit(uploadedLiterature);
- this.literatureForm.resetForm();
- },
- (error: any) => {
- this.errorMessage = 'An error occurred. Please try again later.';
- }
- );
+ // this.salesLiteratureService.uploadLiterature(formData).subscribe(
+ // (response: any) => {
+ // uploadedLiterature.fileUrl = response.fileUrl;
+ // this.successMessage = 'File uploaded successfully.';
+ // this.literatureChange.emit(uploadedLiterature);
+ // this.literatureForm.resetForm();
+ // this.fileInput.nativeElement.value = '';
+ // },
+ // (error: any) => {
+ // this.errorMessage = 'An error occurred. Please try again later.';
+ // }
+ // );
diff --git a/src/app/parts/referral-form/referral-form.component.html b/src/app/parts/referral-form/referral-form.component.html
index cd40765..374c9cd 100644
--- a/src/app/parts/referral-form/referral-form.component.html
+++ b/src/app/parts/referral-form/referral-form.component.html
@@ -5 +5 @@
- <input matInput placeholder="顧客名" disabled [(ngModel)]="referral.customerName" name="customerName">
+ <input matInput placeholder="顧客名" disabled [(ngModel)]="referral.customerId" name="customerName">
diff --git a/src/app/parts/referral-form/referral-form.component.ts b/src/app/parts/referral-form/referral-form.component.ts
index 4698f59..8cd66b2 100644
--- a/src/app/parts/referral-form/referral-form.component.ts
+++ b/src/app/parts/referral-form/referral-form.component.ts
@@ -44 +44 @@ export class ReferralFormComponent implements OnInit {
- if (this.referralForm.controls.referralDate.hasError('required')) {
+ if (this.referralForm.controls['referralDate'].hasError('required')) {
@@ -47 +47 @@ export class ReferralFormComponent implements OnInit {
- if (this.referralForm.controls.referralDate.hasError('matDatepickerParse')) {
+ if (this.referralForm.controls['referralDate'].hasError('matDatepickerParse')) {
@@ -54 +54 @@ export class ReferralFormComponent implements OnInit {
- if (this.referralForm.controls.status.hasError('required')) {
+ if (this.referralForm.controls['status'].hasError('required')) {
@@ -61 +61 @@ export class ReferralFormComponent implements OnInit {
- if (this.referralForm.controls.notes.hasError('maxlength')) {
+ if (this.referralForm.controls['notes'].hasError('maxlength')) {
@@ -67 +67 @@ export class ReferralFormComponent implements OnInit {
- @ViewChild('picker') picker: MatDatepicker<Date>;
+ // @ViewChild('picker') picker: MatDatepicker<Date>;
diff --git a/src/app/parts/referral-list/referral-list.component.html b/src/app/parts/referral-list/referral-list.component.html
index 258441c..b9463db 100644
--- a/src/app/parts/referral-list/referral-list.component.html
+++ b/src/app/parts/referral-list/referral-list.component.html
@@ -4 +4 @@
- <input matInput (keyup)="applyFilter($event.target.value)" placeholder="顧客名またはステータスで検索">
+ <input matInput (keyup)="applyFilter($event.target['value'])" placeholder="顧客名またはステータスで検索">
diff --git a/src/app/parts/sales-history/sales-history.component.ts b/src/app/parts/sales-history/sales-history.component.ts
index 71cf4dc..65e4a57 100644
--- a/src/app/parts/sales-history/sales-history.component.ts
+++ b/src/app/parts/sales-history/sales-history.component.ts
@@ -7 +7 @@ import { SalesService } from '../../services';
-import { SaleDetailsDialogComponent } from '../../dialogs/sale-details-dialog.component';
+// import { SaleDetailsDialogComponent } from '../../dialogs/sale-details-dialog.component';
@@ -35,8 +35,9 @@ export class SalesHistoryComponent implements OnInit {
- const dialogRef = this.dialog.open(SaleDetailsDialogComponent, {
- width: '500px',
- data: sale
- });
-
- dialogRef.afterClosed().subscribe(result => {
- console.log('The dialog was closed');
- });
+ // TOOD: Implement
+ // const dialogRef = this.dialog.open(SaleDetailsDialogComponent, {
+ // width: '500px',
+ // data: sale
+ // });
+
+ // dialogRef.afterClosed().subscribe(result => {
+ // console.log('The dialog was closed');
+ // });
diff --git a/src/app/parts/sales-literature-list/sales-literature-list.component.ts b/src/app/parts/sales-literature-list/sales-literature-list.component.ts
index eb0185a..65eed98 100644
--- a/src/app/parts/sales-literature-list/sales-literature-list.component.ts
+++ b/src/app/parts/sales-literature-list/sales-literature-list.component.ts
@@ -6,2 +6,2 @@ import { SalesLiteratureService } from '../../services';
-import { LiteratureDetailsDialogComponent } from '../../dialogs/literature-details-dialog.component';
-import { UploadLiteratureDialogComponent } from '../../dialogs/upload-literature-dialog.component';
+import { LiteratureDetailsDialogComponent } from '../../dialogs/literature-details-dialog/literature-details-dialog.component';
+// import { UploadLiteratureDialogComponent } from '../../dialogs/upload-literature-dialog.component';
@@ -21 +21 @@ export class SalesLiteratureListComponent implements OnInit {
- literatures: SalesLiterature[];
+ // literatures: SalesLiterature[];
@@ -40,3 +40,3 @@ export class SalesLiteratureListComponent implements OnInit {
- const dialogRef = this.dialog.open(UploadLiteratureDialogComponent, {
- width: '500px'
- });
+ // const dialogRef = this.dialog.open(UploadLiteratureDialogComponent, {
+ // width: '500px'
+ // });
@@ -44,5 +44,5 @@ export class SalesLiteratureListComponent implements OnInit {
- dialogRef.afterClosed().subscribe(result => {
- if (result) {
- this.getSalesLiterature();
- }
- });
+ // dialogRef.afterClosed().subscribe(result => {
+ // if (result) {
+ // this.getSalesLiterature();
+ // }
+ // });
diff --git a/src/app/parts/sales-performance/sales-performance.component.html b/src/app/parts/sales-performance/sales-performance.component.html
index f1c5f6f..a11e9b9 100644
--- a/src/app/parts/sales-performance/sales-performance.component.html
+++ b/src/app/parts/sales-performance/sales-performance.component.html
@@ -33,0 +34,2 @@
+ <!-- TODO chart -->
+ <!-- [colors]="lineChartColors" -->
@@ -35 +37 @@
- [colors]="lineChartColors" [legend]="lineChartLegend" [chartType]="lineChartType"></canvas>
+ [legend]="lineChartLegend" [type]="lineChartType"></canvas>
diff --git a/src/app/parts/sales-performance/sales-performance.component.ts b/src/app/parts/sales-performance/sales-performance.component.ts
index 1ea14df..fff15f1 100644
--- a/src/app/parts/sales-performance/sales-performance.component.ts
+++ b/src/app/parts/sales-performance/sales-performance.component.ts
@@ -3,2 +3,2 @@ import { Component, Input, OnInit } from '@angular/core';
-import { ChartDataSets, ChartOptions, ChartType } from 'chart.js';
-import { Color, Label } from 'ng2-charts';
+import { ChartDataset, ChartOptions, ChartType } from 'chart.js';
+// import { Color, Label } from 'ng2-charts';
@@ -17,2 +17,2 @@ export class SalesPerformanceComponent implements OnInit {
- lineChartData: ChartDataSets[] = [];
- lineChartLabels: Label[] = [];
+ lineChartData: ChartDataset[] = [];
+ lineChartLabels: string[] = [];
@@ -22 +22 @@ export class SalesPerformanceComponent implements OnInit {
- xAxes: [{
+ x: {
@@ -24 +24 @@ export class SalesPerformanceComponent implements OnInit {
- fontColor: 'rgba(0,0,0,0.5)'
+ color: 'rgba(0,0,0,0.5)'
@@ -26,2 +26,2 @@ export class SalesPerformanceComponent implements OnInit {
- }],
- yAxes: [{
+ },
+ y: {
@@ -29,2 +29,3 @@ export class SalesPerformanceComponent implements OnInit {
- fontColor: 'rgba(0,0,0,0.5)',
- beginAtZero: true
+ color: 'rgba(0,0,0,0.5)',
+ // beginAtZero: true,
+ }
@@ -32 +32,0 @@ export class SalesPerformanceComponent implements OnInit {
- }]
@@ -35 +35 @@ export class SalesPerformanceComponent implements OnInit {
- lineChartColors: Color[] = [
+ lineChartColors: any[] = [
diff --git a/src/app/parts/shared-information/shared-information.component.ts b/src/app/parts/shared-information/shared-information.component.ts
index 544fcd3..8b99ea7 100644
--- a/src/app/parts/shared-information/shared-information.component.ts
+++ b/src/app/parts/shared-information/shared-information.component.ts
@@ -6 +6 @@ import { MatDialog } from '@angular/material/dialog';
-import { SharedInformationDialogComponent } from '../../dialogs/shared-information-dialog/shared-information-dialog.component';
+// import { SharedInformationDialogComponent } from '../../dialogs/shared-information-dialog/shared-information-dialog.component';
@@ -29,3 +29,3 @@ export class SharedInformationComponent {
- this.dialog.open(SharedInformationDialogComponent, {
- data: row
- });
+ // this.dialog.open(SharedInformationDialogComponent, {
+ // data: row
+ // });
diff --git a/src/app/parts/side-menu/side-menu.component.html b/src/app/parts/side-menu/side-menu.component.html
index 260241e..9b10fe9 100644
--- a/src/app/parts/side-menu/side-menu.component.html
+++ b/src/app/parts/side-menu/side-menu.component.html
@@ -1,3 +1,3 @@
-<mat-sidenav-container class="sidenav-container">
- <mat-sidenav #drawer class="sidenav" fixedInViewport [attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'"
- [mode]="(isHandset$ | async) ? 'over' : 'side'" [opened]="!(isHandset$ | async)">
+<!-- <mat-sidenav-container class="sidenav-container"> -->
+<!-- <mat-sidenav #drawer class="sidenav" fixedInViewport [attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'"
+ [mode]="(isHandset$ | async) ? 'over' : 'side'" [opened]="!(isHandset$ | async)"> -->
@@ -6 +6 @@
- <span class="username">{{ user.firstName }} {{ user.lastName }}</span>
+ <span class="username">{{ user?.firstName }} {{ user?.lastName }}</span>
@@ -46 +46,2 @@
- </mat-sidenav>
+<!-- </mat-sidenav> -->
+<!--
@@ -50 +51 @@
-</mat-sidenav-container>
\ No newline at end of file
+</mat-sidenav-container> -->
\ No newline at end of file
diff --git a/src/app/parts/side-menu/side-menu.component.ts b/src/app/parts/side-menu/side-menu.component.ts
index 325c85d..bc4d6a1 100644
--- a/src/app/parts/side-menu/side-menu.component.ts
+++ b/src/app/parts/side-menu/side-menu.component.ts
@@ -5 +5 @@ import { Observable } from 'rxjs';
-import { AuthService } from '../../services';
+import { AuthService, UserService } from '../../services';
@@ -22,2 +22,2 @@ export class SideMenuComponent implements OnInit {
- constructor(private authService: AuthService) {
- this.isHandset$ = this.authService.isHandset$;
+ constructor(private authService: AuthService, private userService: UserService) {
+ // this.isHandset$ = this.authService.isHandset$;
@@ -27 +27 @@ export class SideMenuComponent implements OnInit {
- this.authService.getUserProfile().subscribe(user => {
+ this.userService.getUserProfile().subscribe(user => {
@@ -35,7 +35,7 @@ export class SideMenuComponent implements OnInit {
- this.isHandset$.subscribe(isHandset => {
- if (isHandset) {
- this.drawer.close();
- } else {
- this.drawer.open();
- }
- });
+ // this.isHandset$.subscribe(isHandset => {
+ // if (isHandset) {
+ // this.drawer.close();
+ // } else {
+ // this.drawer.open();
+ // }
+ // });
diff --git a/src/app/parts/task-form/task-form.component.html b/src/app/parts/task-form/task-form.component.html
index 2e129dd..4601176 100644
--- a/src/app/parts/task-form/task-form.component.html
+++ b/src/app/parts/task-form/task-form.component.html
@@ -2,2 +2,2 @@
- <form class="task-form" #taskForm="ngForm" (ngSubmit)="onSubmit()">
- <h2 class="task-form-title">{{ task ? 'タスク編集' : 'タスク作成' }}</h2>
+ <form class="task-form" #taskForm="ngForm" (ngSubmit)="onSubmit()" action="javascript:void(0)">
+ <h2 class="task-form-title">{{ (task?.id||task?.id===0) ? 'タスク編集' : 'タスク作成' }}</h2>
@@ -6 +6 @@
- <mat-error *ngIf="taskForm.controls['title'].invalid">タスク名は必須です。</mat-error>
+ <mat-error *ngIf="taskForm.controls['title']?.invalid">タスク名は必須です。</mat-error>
@@ -15 +15 @@
- <mat-error *ngIf="taskForm.controls['startDate'].invalid">開始日は必須です。</mat-error>
+ <mat-error *ngIf="taskForm.controls['startDate']?.invalid">開始日は必須です。</mat-error>
@@ -21,2 +21,2 @@
- <mat-error *ngIf="taskForm.controls['endDate'].invalid">終了日は必須です。</mat-error>
- <mat-error *ngIf="taskForm.controls['endDate'].hasError('matDatepickerMax')">開始日より後の日付を選択してください。</mat-error>
+ <mat-error *ngIf="taskForm.controls['endDate']?.invalid">終了日は必須です。</mat-error>
+ <mat-error *ngIf="taskForm.controls['endDate']?.hasError('matDatepickerMax')">開始日より後の日付を選択してください。</mat-error>
@@ -25,5 +25,8 @@
- <input matInput [matTimepicker]="reminderTimePicker" name="reminderTime" placeholder="リマインダー" [(ngModel)]="task.reminder.time">
- <mat-timepicker-toggle matSuffix [for]="reminderTimePicker"></mat-timepicker-toggle>
- <mat-timepicker #reminderTimePicker></mat-timepicker>
- <mat-error *ngIf="taskForm.controls['reminderTime'].hasError('matDatepickerMin')">開始日より後の時間を選択してください。</mat-error>
- <mat-error *ngIf="taskForm.controls['reminderTime'].hasError('matDatepickerMax')">終了日より前の時間を選択してください。</mat-error>
+ <input matTimepicker #t="matTimepicker" #time="ngModel"
+ [strict]="false" id="timepicker-example" mode="24h" [ngModel]="task.reminder?.time"
+ placeholder="Please select time..." name="time" />
+ <!-- <input matInput [matTimepicker]="reminderTimePicker" name="reminderTime" placeholder="リマインダー" [(ngModel)]="task.reminder.time"> -->
+ <!-- <mat-timepicker-toggle matSuffix [for]="reminderTimePicker"></mat-timepicker-toggle>
+ <mat-timepicker #reminderTimePicker></mat-timepicker> -->
+ <mat-error *ngIf="taskForm.controls['reminderTime']?.hasError('matDatepickerMin')">開始日より後の時間を選択してください。</mat-error>
+ <mat-error *ngIf="taskForm.controls['reminderTime']?.hasError('matDatepickerMax')">終了日より前の時間を選択してください。</mat-error>
@@ -38 +41 @@
- <mat-error *ngIf="taskForm.controls['status'].invalid">ステータスは必須です。</mat-error>
+ <mat-error *ngIf="taskForm.controls['status']?.invalid">ステータスは必須です。</mat-error>
diff --git a/src/app/parts/task-form/task-form.component.scss b/src/app/parts/task-form/task-form.component.scss
index e69de29..74dcda1 100644
--- a/src/app/parts/task-form/task-form.component.scss
+++ b/src/app/parts/task-form/task-form.component.scss
@@ -0,0 +1,4 @@
+.task-form-buttons {
+ display: flex;
+ justify-content: space-between;
+}
\ No newline at end of file
diff --git a/src/app/parts/task-form/task-form.component.ts b/src/app/parts/task-form/task-form.component.ts
index 7504ce2..9996b1a 100644
--- a/src/app/parts/task-form/task-form.component.ts
+++ b/src/app/parts/task-form/task-form.component.ts
@@ -15 +15 @@ export class TaskFormComponent implements OnInit {
- @Input() task: Task;
+ @Input() task: Task = {} as Task;
@@ -43,0 +44 @@ export class TaskFormComponent implements OnInit {
+ this.taskForm.resetForm();
@@ -48 +49 @@ export class TaskFormComponent implements OnInit {
- this.taskChange.emit(null);
+ this.taskChange.emit({} as Task);
diff --git a/src/app/parts/task-list/task-list.component.ts b/src/app/parts/task-list/task-list.component.ts
index 56fedf5..9eea7b7 100644
--- a/src/app/parts/task-list/task-list.component.ts
+++ b/src/app/parts/task-list/task-list.component.ts
@@ -4 +4 @@ import { MatDialog } from '@angular/material/dialog';
-import { Task } from '../../models';
+import { Task, TaskStatus } from '../../models';
@@ -6 +6 @@ import { TaskService } from '../../services';
-import { TaskDetailsDialogComponent } from '../../dialogs/task-details-dialog.component';
+import { TaskDetailsDialogComponent } from '../../dialogs/task-details-dialog/task-details-dialog.component';
@@ -45 +45,2 @@ export class TaskListComponent implements OnInit {
- this.taskService.deleteTask(task.id).subscribe(() => {
+ task.status = TaskStatus.COMPLETED;
+ this.taskService.updateTask(task).subscribe(() => {
diff --git a/src/app/parts/team-member-list/team-member-list.component.html b/src/app/parts/team-member-list/team-member-list.component.html
index 4684281..dd058e7 100644
--- a/src/app/parts/team-member-list/team-member-list.component.html
+++ b/src/app/parts/team-member-list/team-member-list.component.html
@@ -4 +4 @@
- <input matInput (keyup)="applyFilter($event.target.value)" placeholder="名前またはメールアドレスで検索">
+ <input matInput (keyup)="applyFilter($event.target['value'])" placeholder="名前またはメールアドレスで検索">
diff --git a/src/app/parts/training-participation/training-participation.component.ts b/src/app/parts/training-participation/training-participation.component.ts
index 51fd131..15c255d 100644
--- a/src/app/parts/training-participation/training-participation.component.ts
+++ b/src/app/parts/training-participation/training-participation.component.ts
@@ -39 +39 @@ export class TrainingParticipationComponent implements OnInit {
- calculateProgress(): void {
+ calculateProgress(): number {
@@ -51,0 +52 @@ export class TrainingParticipationComponent implements OnInit {
+ return this.progress;
作ったものの説明
ここでいう「作ったもの」は先ほどのモックではなく、それを作るために作ったGPT API呼び出し用スクリプトのことです。
"ワークフロー作った"というと響きはかっこいいですけど、実際はすげぇ地道にプロンプト投げるスクリプトを書いただけです。。
ユーザーシナリオを入力すると、その入力を基に画面設計(全体)、サービス設計、モデル設計、サンプルデータ作成、画面設計(個別)、画面作成(html/typescript)等々と、全16ステップの工程を繋げて実行するスクリプトになっています。
一応ステップごとに分けて書いてあるので、それぞれで何をしているかはソースを見て頂くとすぐわかると思います。
※プロンプトを全部英語にしているのはトークン数削減のためで、それ以上でも以下でもないです。
色々試行錯誤した結果、「GPTで全部作る」のではく、ある程度フレームを作っておいて、自由度が高いところを「GPTに穴埋めしてもらう」的なコンセプトで作っています。(※とはいえ今はフレームが緩々なのでコンセプト通りの実装とは言えませんが、、)
なので、いわゆる古典的なソースコード自動生成(ドメインモデルからプログラム言語に変換するだけ)的な機能と、スクリプト投げるだけ機能を組み合わせたようなスクリプトになっています。
使い方
ソースと同じ階層に「000-requirements.md」というファイル名で作りたいシステムのユーザーシナリオを書いてから動かすとAngularの画面セットが出来上がってきます。
動かし方は generator.js を実行するだけです。
node generator.js
APIはGPT-3.5と4を織り交ぜて使っています。
全部4にすると高くつくのと、あと意外と3.5の方が精度が高い場合もあるので、そのあたりは匙加減でやってます。
アクセス権が無い方は全部3.5にしてもまぁ何かはできると思います。
今回作ったものでだいたい30万トークン≒約50円くらいでした。
ソース生成系を全部GPT-4にすると大体600円くらいかかります。
下の方にあるこの辺↓のところがステップを実行しているところで、
initPromptでプロンプトを作成して、runで実行です。
obj = new Step000_RequirementsToComponentList();
obj.initPrompt();
await obj.run();
一気通貫でも動くと思いますが、私は結構動かしたいところ以外はコメントアウトして使っています。
特にSTEP12以降はものによっては大量実行になるので、一旦initPromptでプロンプトの出来栄えを見て、いくつかPlaygroundで実行してみて結果が良さそうだったらrunを動かす、みたいな使い方をしています。
000-requirements.mdのサンプルはこちら↓
なお、このユーザーシナリオもChatGPTで「銀行で使うCRMを作りたいです。ユーザーシナリオを作ってください。英語で。」と書いたら出てきたやつをそのまま張ってるだけです。
000-requirements.md
-
new customer registration scenario:.
A salesperson registers new customer information and enters basic information such as name, address, phone number, email address, occupation, annual income, financial assets, and family structure. -
customer information edit scenario: A salesperson searches for existing customer information.
The salesperson retrieves existing customer information and updates or corrects the information. The change history is also recorded. -
customer search scenario: The salesperson searches for a customer.
The salesperson searches for a customer using information such as name, address, phone number, email address, etc., and displays detailed information.
Customer Segmentation Scenario: The salesperson searches for a customer by age, occupation, or occupation.
The salesperson classifies customers based on criteria such as age, occupation, annual income, financial assets, family structure, etc., and obtains information to make product proposals and provide services tailored to each segment.
-
sales and transaction history management scenario:.
Salespeople can list sales and transaction history for each customer and understand customer needs based on past transaction data. -
task and schedule management scenario
This scenario allows salespeople to manage tasks and schedules for appointments with customers and sales activities, and use the reminder function to confirm appointments and track task completion status. -
customer response history management scenario: Salespeople can manage their customer response history.
Salespeople manage their correspondence history with customers, including phone calls, email correspondence, and visit history, to obtain information for appropriate follow-up. -
sales goal management scenario: Salespeople set their own sales goals.
Enables salespeople to set their own sales goals and monitor their achievement. Visualization of goal progress leads to increased motivation. -
sales performance reporting scenario
Salespeople regularly report their sales performance and visualize KPIs such as sales, number of transactions, and number of new customers acquired. This information is shared with superiors and team members to help improve sales activities and revise strategies. -
Claims handling scenario: A scenario in which a salesperson responds to a claim or complaint from a customer.
Salespeople receive complaints and inquiries from customers and record their response history to obtain information for finding appropriate solutions. Also, the system analyzes the trend of complaints to improve the service. -
reference information management scenario:.
Salespeople manage referral information and references from customers and use it as an effective means of developing new customers.
Sales literature management scenario: Salespeople manage product literature and sales literature.
Salespeople can centrally manage product information and sales tools so that they can quickly retrieve the appropriate materials when making a proposal to a client.
-
sales team collaboration scenario
Salespeople can share information within their team to improve the efficiency of customer service and sales activities. They can also improve their own skills by learning from other salespeople's success stories and know-how. -
sales training management scenarios: Salespeople can learn from other salespeople's success stories and know-how to improve their own skills.
Enables salespeople to manage their participation history in internal training programs and external seminars, and to check their skill acquisition status and training effectiveness.
Based on these user scenarios, a CRM system for bank salespeople can be designed and developed to improve the efficiency of customer service and sales activities and increase sales.
出来上がったアプリのモックと実行ログ集とか諸々セットでgithubにアップしてあります。
今回はソースを大量に貼ったせいで重くてこれ以上書けないのでここまでとします。
次回以降、気が向いたらサーバー編とワークフローの詳解をやります。