| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
- import { FormsModule } from '@angular/forms';
- import { DankaService } from '../../services/dankaService';
- import { FamilyService } from '../../services/family-service';
- import { EventService } from '../../services/event-service';
- import { EventStatus, EventTarget, EventType } from '../../models/event';
- import { AppHeader } from '../../share/header/app-header';
- import { AppSideMenu } from '../../share/side-menu/app-side-menu';
-
- @Component({
- selector: 'app-event',
- imports: [AppHeader, AppSideMenu, FormsModule],
- templateUrl: './event.html',
- styleUrl: './event.scss',
- })
- export class EventPage implements OnInit{
- eventTargets: EventTarget[] = [];
- isLoading = true;
- targetYear: number = new Date().getFullYear();
- selectedEventType: EventType | 'all' = 'all';
- selectedStatus: EventStatus | 'all' = 'all';
- searchKeyword = '';
- eventStatuses: EventStatus[] = ['未案内', '案内済'];
- yearOptions: number[] = [
- this.targetYear - 1,
- this.targetYear,
- this.targetYear + 1,
- this.targetYear + 2,
- ];
- eventTypeFilters: { label: string; value: EventType | 'all' }[] = [
- { label: 'すべて', value: 'all' },
- { label: '稚児行列', value: '稚児行列' },
- { label: '七五三', value: '七五三' },
- { label: '成人式', value: '成人式' },
- { label: '米寿', value: '米寿' },
- ];
- statusFilters: { label: string; value: EventStatus | 'all' }[] = [
- { label: 'すべて', value: 'all' },
- { label: '未案内', value: '未案内' },
- { label: '案内済', value: '案内済' },
- ];
- private eventRequestId = 0;
-
- constructor(
- private dankaService: DankaService,
- private familyService: FamilyService,
- private eventService: EventService,
- private cdr: ChangeDetectorRef,
- ) { }
-
- ngOnInit(): void {
- this.init();
- }
-
- async init(): Promise<void> {
- await this.createEventTargetList();
- }
-
- async createEventTargetList(): Promise<void> {
- const requestId = ++this.eventRequestId;
- const targetYear = this.targetYear;
- const selectedEventType = this.selectedEventType;
- const eventTargets: EventTarget[] = [];
-
- if (this.eventTargets.length === 0) {
- this.isLoading = true;
- this.cdr.detectChanges();
- }
-
- const families = await this.familyService.getFamilyList();
-
- for (const family of families) {
- const birthDate = this.parseDate(family.birthDate);
- if (!birthDate) continue;
-
- const age = targetYear - birthDate.getFullYear();
- const eventTypes = this.getEventTypes(age);
- if (eventTypes.length === 0) continue;
-
- // ★ここが修正ポイント(await)
- const danka = await this.dankaService.getDankaById(family.dankaId);
-
- for (const eventType of eventTypes) {
- if (
- selectedEventType !== 'all' &&
- selectedEventType !== eventType
- ) {
- continue;
- }
-
- const id = `${family.id}-${eventType}`;
-
- const defaultStatus: EventStatus =
- Number(family.id) % 2 === 0 ? '案内済' : '未案内';
-
- eventTargets.push({
- id,
- dankaId: family.dankaId,
- name: family.name,
- furigana: family.furigana,
- householdName: danka?.householdName ?? '不明',
- relationship: family.relationship || '未登録',
- birthDate: this.formatDateForValue(birthDate),
- age,
- eventType,
- note: family.note,
- status: this.eventService.getEventStatus(id, defaultStatus),
- });
- }
- }
-
- if (requestId !== this.eventRequestId) {
- return;
- }
-
- this.eventTargets = eventTargets.sort(
- (a, b) =>
- this.getEventSortOrder(a.eventType) -
- this.getEventSortOrder(b.eventType) ||
- a.age - b.age ||
- a.name.localeCompare(b.name, 'ja'),
- );
- this.isLoading = false;
- this.cdr.detectChanges();
- }
-
- changeEventType(eventType: EventType | 'all'): void {
- this.selectedEventType = eventType;
- this.createEventTargetList();
- }
-
- get filteredEventTargets(): EventTarget[] {
- const keyword = this.searchKeyword.trim();
-
- return this.eventTargets.filter((target) => {
- const matchesStatus = this.selectedStatus === 'all' || target.status === this.selectedStatus;
- const matchesKeyword =
- !keyword ||
- [
- target.name,
- target.furigana,
- target.householdName,
- target.relationship,
- target.birthDate,
- target.eventType,
- target.note,
- target.status,
- ].some((value) => this.includesKeyword(value, keyword));
-
- return matchesStatus && matchesKeyword;
- });
- }
-
- changeStatus(target: EventTarget, status: EventStatus): void {
- target.status = status;
- this.eventService.saveEventStatus(target.id, status);
- }
-
- private getEventTypes(age: number): EventType[] {
- const eventTypes: EventType[] = [];
-
- if (age >= 3 && age <= 12) {
- eventTypes.push('稚児行列');
- }
- if ([3, 5, 7].includes(age)) {
- eventTypes.push('七五三');
- }
- if (age === 20) {
- eventTypes.push('成人式');
- }
- if (age === 88) {
- eventTypes.push('米寿');
- }
-
- return eventTypes;
- }
-
- private getEventSortOrder(eventType: EventType): number {
- return ['稚児行列', '七五三', '成人式', '米寿'].indexOf(eventType);
- }
-
- private parseDate(value: unknown): Date | null {
- if (!value) {
- return null;
- }
-
- if (value instanceof Date) {
- return value;
- }
-
- if (typeof value === 'object' && 'toDate' in value && typeof value.toDate === 'function') {
- return value.toDate();
- }
-
- if (typeof value !== 'string') {
- return null;
- }
-
- const [year, month, day] = value.split('-').map(Number);
- if (!year || !month || !day) {
- return null;
- }
- return new Date(year, month - 1, day);
- }
-
- private includesKeyword(value: unknown, keyword: string): boolean {
- return String(value ?? '').includes(keyword);
- }
-
- private formatDateForValue(date: Date): string {
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, '0');
- const day = String(date.getDate()).padStart(2, '0');
- return `${year}-${month}-${day}`;
- }
- }
|