Ei kuvausta
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

event.ts 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import { Component, OnInit } from '@angular/core';
  2. import { FormsModule } from '@angular/forms';
  3. import { DankaService } from '../../services/dankaService';
  4. import { FamilyService } from '../../services/family-service';
  5. import { EventService } from '../../services/event-service';
  6. import { EventStatus, EventTarget, EventType } from '../../models/event';
  7. import { AppHeader } from '../../share/header/app-header';
  8. import { AppSideMenu } from '../../share/side-menu/app-side-menu';
  9. @Component({
  10. selector: 'app-event',
  11. imports: [AppHeader, AppSideMenu, FormsModule],
  12. templateUrl: './event.html',
  13. styleUrl: './event.scss',
  14. })
  15. export class EventPage implements OnInit{
  16. eventTargets: EventTarget[] = [];
  17. targetYear: number = new Date().getFullYear();
  18. selectedEventType: EventType | 'all' = 'all';
  19. selectedStatus: EventStatus | 'all' = 'all';
  20. searchKeyword = '';
  21. eventStatuses: EventStatus[] = ['未案内', '案内済'];
  22. yearOptions: number[] = [
  23. this.targetYear - 1,
  24. this.targetYear,
  25. this.targetYear + 1,
  26. this.targetYear + 2,
  27. ];
  28. eventTypeFilters: { label: string; value: EventType | 'all' }[] = [
  29. { label: 'すべて', value: 'all' },
  30. { label: '稚児行列', value: '稚児行列' },
  31. { label: '七五三', value: '七五三' },
  32. { label: '成人式', value: '成人式' },
  33. { label: '米寿', value: '米寿' },
  34. ];
  35. statusFilters: { label: string; value: EventStatus | 'all' }[] = [
  36. { label: 'すべて', value: 'all' },
  37. { label: '未案内', value: '未案内' },
  38. { label: '案内済', value: '案内済' },
  39. ];
  40. constructor(
  41. private dankaService: DankaService,
  42. private familyService: FamilyService,
  43. private eventService: EventService,
  44. ) { }
  45. ngOnInit(): void {
  46. this.init();
  47. }
  48. async init(): Promise<void> {
  49. await this.createEventTargetList();
  50. }
  51. async createEventTargetList(): Promise<void> {
  52. this.eventTargets = [];
  53. const families = await this.familyService.getFamilyList();
  54. for (const family of families) {
  55. const birthDate = this.parseDate(family.birthDate);
  56. if (!birthDate) continue;
  57. const age = this.targetYear - birthDate.getFullYear();
  58. const eventTypes = this.getEventTypes(age);
  59. if (eventTypes.length === 0) continue;
  60. // ★ここが修正ポイント(await)
  61. const danka = await this.dankaService.getDankaById(family.dankaId);
  62. for (const eventType of eventTypes) {
  63. if (
  64. this.selectedEventType !== 'all' &&
  65. this.selectedEventType !== eventType
  66. ) {
  67. continue;
  68. }
  69. const id = `${family.id}-${eventType}`;
  70. const defaultStatus: EventStatus =
  71. Number(family.id) % 2 === 0 ? '案内済' : '未案内';
  72. this.eventTargets.push({
  73. id,
  74. dankaId: family.dankaId,
  75. name: family.name,
  76. furigana: family.furigana,
  77. householdName: danka?.householdName ?? '不明',
  78. relationship: family.relationship || '未登録',
  79. birthDate: family.birthDate,
  80. age,
  81. eventType,
  82. note: family.note,
  83. status: this.eventService.getEventStatus(id, defaultStatus),
  84. });
  85. }
  86. }
  87. this.eventTargets.sort(
  88. (a, b) =>
  89. this.getEventSortOrder(a.eventType) -
  90. this.getEventSortOrder(b.eventType) ||
  91. a.age - b.age ||
  92. a.name.localeCompare(b.name, 'ja'),
  93. );
  94. }
  95. changeEventType(eventType: EventType | 'all'): void {
  96. this.selectedEventType = eventType;
  97. this.createEventTargetList();
  98. }
  99. get filteredEventTargets(): EventTarget[] {
  100. const keyword = this.searchKeyword.trim();
  101. return this.eventTargets.filter((target) => {
  102. const matchesStatus = this.selectedStatus === 'all' || target.status === this.selectedStatus;
  103. const matchesKeyword =
  104. !keyword ||
  105. [
  106. target.name,
  107. target.furigana,
  108. target.householdName,
  109. target.relationship,
  110. target.birthDate,
  111. target.eventType,
  112. target.note,
  113. target.status,
  114. ].some((value) => value.includes(keyword));
  115. return matchesStatus && matchesKeyword;
  116. });
  117. }
  118. changeStatus(target: EventTarget, status: EventStatus): void {
  119. target.status = status;
  120. this.eventService.saveEventStatus(target.id, status);
  121. }
  122. private getEventTypes(age: number): EventType[] {
  123. const eventTypes: EventType[] = [];
  124. if (age >= 3 && age <= 12) {
  125. eventTypes.push('稚児行列');
  126. }
  127. if ([3, 5, 7].includes(age)) {
  128. eventTypes.push('七五三');
  129. }
  130. if (age === 20) {
  131. eventTypes.push('成人式');
  132. }
  133. if (age === 88) {
  134. eventTypes.push('米寿');
  135. }
  136. return eventTypes;
  137. }
  138. private getEventSortOrder(eventType: EventType): number {
  139. return ['稚児行列', '七五三', '成人式', '米寿'].indexOf(eventType);
  140. }
  141. private parseDate(value: string): Date | null {
  142. const [year, month, day] = value.split('-').map(Number);
  143. if (!year || !month || !day) {
  144. return null;
  145. }
  146. return new Date(year, month - 1, day);
  147. }
  148. }