Нема описа
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.

dankaService.ts 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import { Injectable } from '@angular/core';
  2. import {
  3. collection,
  4. getDocs,
  5. doc,
  6. getDoc,
  7. setDoc,
  8. deleteDoc,
  9. updateDoc
  10. } from 'firebase/firestore';
  11. import { db } from '../firebase';
  12. import { Danka } from '../models/danka';
  13. @Injectable({
  14. providedIn: 'root',
  15. })
  16. export class DankaService {
  17. private path = 'danka';
  18. private readonly recentDankaStorageKey = 'kaimyo-management.recent-danka';
  19. // 一覧
  20. async getDankaList(): Promise<Danka[]> {
  21. const snap = await getDocs(collection(db, this.path));
  22. return snap.docs.map(d => ({
  23. id: d.id,
  24. ...(d.data() as Omit<Danka, 'id'>)
  25. }));
  26. }
  27. // 1件
  28. async getDankaById(id: string): Promise<Danka | undefined> {
  29. const ref = doc(db, this.path, id);
  30. const snap = await getDoc(ref);
  31. if (!snap.exists()) return undefined;
  32. return {
  33. id: snap.id,
  34. ...(snap.data() as Omit<Danka, 'id'>)
  35. };
  36. }
  37. // 作成・更新
  38. async saveDanka(danka: Danka): Promise<void> {
  39. const ref = doc(db, this.path, danka.id);
  40. await setDoc(ref, danka);
  41. }
  42. // 部分更新
  43. async updateDanka(id: string, data: Partial<Danka>): Promise<void> {
  44. const ref = doc(db, this.path, id);
  45. await updateDoc(ref, data as any);
  46. }
  47. // 削除
  48. async deleteDanka(id: string): Promise<void> {
  49. const ref = doc(db, this.path, id);
  50. await deleteDoc(ref);
  51. }
  52. // -----------------------------
  53. // 最近開いた檀家
  54. // -----------------------------
  55. private getRecentDankaIds(): string[] {
  56. if (!this.canUseLocalStorage()) return [];
  57. const value = localStorage.getItem(this.recentDankaStorageKey);
  58. if (!value) return [];
  59. try {
  60. const parsed = JSON.parse(value);
  61. return Array.isArray(parsed)
  62. ? parsed.filter((id): id is string => typeof id === 'string')
  63. : [];
  64. } catch {
  65. return [];
  66. }
  67. }
  68. private saveRecentDankaIds(ids: string[]): void {
  69. if (!this.canUseLocalStorage()) return;
  70. localStorage.setItem(this.recentDankaStorageKey, JSON.stringify(ids));
  71. }
  72. private canUseLocalStorage(): boolean {
  73. return typeof localStorage !== 'undefined';
  74. }
  75. // ★ここが重要:async化
  76. async recordDankaOpened(id: string): Promise<void> {
  77. const danka = await this.getDankaById(id);
  78. if (!danka) return;
  79. const recentIds = [
  80. id,
  81. ...this.getRecentDankaIds().filter(rid => rid !== id),
  82. ].slice(0, 5);
  83. this.saveRecentDankaIds(recentIds);
  84. }
  85. // ★ここも async 必須
  86. async getRecentDankaList(limit = 5): Promise<Danka[]> {
  87. const ids = this.getRecentDankaIds().slice(0, limit);
  88. const list = await Promise.all(
  89. ids.map(id => this.getDankaById(id))
  90. );
  91. const filtered = list.filter((d): d is Danka => d !== undefined);
  92. if (filtered.length > 0) {
  93. return filtered;
  94. }
  95. // fallback(updatedAtがある前提なら)
  96. const all = await this.getDankaList();
  97. return [...all]
  98. .sort((a: any, b: any) =>
  99. (b.updatedAt ?? '').localeCompare(a.updatedAt ?? '')
  100. )
  101. .slice(0, limit);
  102. }
  103. }