| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601 |
- <app-header></app-header>
-
-
- <div class="danka-detail-page">
- <app-side-menu></app-side-menu>
-
- <main class="danka-detail-main">
- <section class="detail-panel">
- @if (danka) {
- <div class="page-title-row">
- <div>
- <h1>
- 檀家詳細 - {{ danka.householdName }}
- </h1>
-
- <nav class="tab-list">
- <button type="button" class="tab-button" [class.active]="selectedTab === 'basic'"
- (click)="selectedTab = 'basic'">
- 基本情報
- </button>
-
- <button type="button" class="tab-button" [class.active]="selectedTab === 'family'"
- (click)="selectedTab = 'family'">
- 家族
- </button>
-
- <button type="button" class="tab-button" [class.active]="selectedTab === 'kakocho'"
- (click)="selectedTab = 'kakocho'">
- 過去帳
- </button>
-
- <button type="button" class="tab-button" [class.active]="selectedTab === 'familyTree'"
- (click)="openFamilyTreeTab()">
- 家系図
- </button>
- </nav>
- </div>
- @if (selectedTab === 'basic') {
- <button type="button" class="edit-button" [routerLink]="['/danka-edit', danka.id]">
- 編集
- </button>
- }
-
- @if (selectedTab === 'kakocho') {
- <button type="button" class="add-button" [routerLink]="['/kakocho-edit', danka.id]">
- 故人を登録
- </button>
- }
- </div>
-
- @if (selectedTab === 'basic' || selectedTab === 'kakocho') {
- <section class="family-summary">
- @if (selectedTab === 'basic') {
- <div class="family-name-area">
- <p class="family-name">{{ danka.householdName }}</p>
- <p class="family-head">更新日: {{ formatUpdatedAt(danka.updatedAt) }}</p>
- </div>
- }
-
- @if (selectedTab === 'kakocho') {
- <div class="family-name-area">
- <p class="family-name">{{ danka.householdName }}の過去帳{{ kakocholist.length }} 名</p>
- </div>
- }
- </section>
- }
-
- @if (selectedTab === 'basic') {
- <div class="detail-content">
- <section class="basic-info-section">
- <div class="section-heading">
- <h2>基本情報</h2>
- </div>
-
- <div class="info-form">
- <div class="info-row">
- <div class="info-label">世帯名</div>
- <div class="info-value">{{ danka.householdName }}</div>
- </div>
-
- <div class="info-row">
- <div class="info-label">世帯主</div>
- <div class="info-value">{{ danka.householder }}</div>
- </div>
-
- <div class="info-row">
- <div class="info-label">郵便番号</div>
- <div class="info-value">{{ danka.postalCode }}</div>
- </div>
-
- <div class="info-row">
- <div class="info-label">住所</div>
- <div class="info-value">{{ danka.address }}</div>
- </div>
-
- <div class="info-row phone-row">
- <div class="info-label">電話番号</div>
-
- <div class="phone-table">
- <div class="phone-header">
- <div>番号</div>
- <div>備考</div>
- </div>
-
- @for (phone of danka.phones; track $index) {
- <div class="phone-item">
- <div>{{ phone.tel }}</div>
- <div>{{ phone.note }}</div>
- </div>
- }
- </div>
- </div>
- </div>
- </section>
-
- <aside class="status-panel">
- <h2>この世帯の状況</h2>
-
- <div class="status-card-list">
- <button type="button" class="status-card" (click)="selectedTab = 'family'">
- <p class="status-label">家族</p>
- <p class="status-count">{{ families.length }} 名</p>
- <p class="status-link">詳細へ</p>
- </button>
-
- <button type="button" class="status-card" (click)="selectedTab = 'kakocho'">
- <p class="status-label">過去帳</p>
- <p class="status-count">{{ kakocholist.length }} 名</p>
- <p class="status-link">詳細へ</p>
- </button>
- </div>
-
- <section class="next-memorial">
- <h3>次の法要</h3>
-
- <div class="memorial-card">
- @if (nextMemorial) {
- <p class="memorial-title">
- {{ nextMemorial.name }} - {{ nextMemorial.memorialType }}
- </p>
- <p class="memorial-text">
- 対象年 {{ nextMemorial.targetYear }} / 没年月日 {{ nextMemorial.deathDate }}
- </p>
- } @else {
- <p class="memorial-title">対象の法要はありません</p>
- <p class="memorial-text">
- 今年の年忌法要対象者がいる場合に表示されます。
- </p>
- }
- </div>
- </section>
- </aside>
- </div>
- }
-
- @if (selectedTab === 'family') {
- <section class="family-tab-content">
- <div class="section-heading">
- <h2>家族情報</h2>
- </div>
-
- <section class="family-list-summary">
- <div>
- <p class="family-list-title">
- {{ danka.householdName }}の家族 {{ families.length }}名
- </p>
- </div>
-
- <p class="family-list-head">
- ※ 世帯主:{{ danka.householder }}
- </p>
- </section>
-
- <section class="family-table-section">
- @if (families.length > 0) {
- <div class="family-table">
- <div class="family-table-header">
- <div>氏名</div>
- <div>ふりがな</div>
- <div>生年月日</div>
- <div>年齢</div>
- <div>続柄</div>
- <div>備考</div>
- <div>操作</div>
- </div>
-
- @for (family of families; track family.id) {
- <div class="family-table-row">
- <div class="family-person-name">
- {{ family.name }}
- </div>
-
- <div>
- {{ family.furigana }}
- </div>
-
- <div>
- {{ family.birthDate || '未登録' }}
- </div>
-
- <div>
- {{ getAge(family.birthDate) }}
- </div>
-
- <div>
- {{ family.relationship || '未登録' }}
- </div>
-
- <div>
- {{ family.note || '' }}
- </div>
- <div class="family-table-action">
- <a class="family-edit-link" [routerLink]="['/danka', danka.id, 'family', family.id, 'edit']">
- 編集
- </a>
- </div>
- </div>
- }
- </div>
- } @else {
- <div class="empty-family-message">
- 登録されている家族情報はありません。
- </div>
- }
- </section>
- </section>
- }
-
- @if (selectedTab === 'kakocho') {
- <section class="coming-soon-section">
- <div class="section-heading">
- <h2>過去帳</h2>
- </div>
-
- <p class="empty-family-message">
- @if (kakocholist.length > 0) {
- <div class="family-table">
- <div class="family-table-header">
- <div>戒名</div>
- <div>俗名</div>
- <div>没年月日</div>
- <div>続柄</div>
- <div>回忌</div>
- <div>備考</div>
- </div>
-
- @for (kakocho of kakocholist; track kakocho.id) {
- <div class="family-table-row">
- <div class="family-person-name">
- {{ kakocho.kaimyo }}
- </div>
-
- <div>
- {{ kakocho.name }}
- </div>
-
- <div>
- {{ formatDeathDateWithYear(kakocho.deathDate) }}
- </div>
-
- <div>
- {{ kakocho.relationship }}
- </div>
-
- <div>
- {{ getKaiki(kakocho.deathDate) }}回忌
- </div>
-
- <div>
- {{ kakocho.note || '' }}
- </div>
- </div>
- }
- </div>
- } @else {
- <div class="empty-family-message">
- 登録されている家族情報はありません。
- </div>
- }
- </p>
- </section>
- }
-
- @if (selectedTab === 'familyTree') {
- <section class="family-tree-tab-content">
- <div class="section-heading">
- <h2>家系図</h2>
- <p>
- 家族情報に登録された親子・配偶者の関係をもとに表示します。
- </p>
- </div>
-
- @if (families.length > 0) {
- <div class="family-tree-layout">
- <section class="family-tree-area">
- <div class="family-tree-toolbar">
- <div>
- <p class="family-tree-title">
- {{ danka.householdName }}の家系図
- </p>
- <p class="family-tree-caption">
- 人物カードを選択すると、右側に関係情報が表示されます。
- </p>
- </div>
-
- <div class="family-tree-action-list">
- <button type="button" class="tree-action-button" [routerLink]="['/danka', danka.id, 'family-new']"
- [queryParams]="{relationMode: 'child', baseFamilyId: selectedFamily?.id}">
- 親子を追加
- </button>
-
- <button type="button" class="tree-action-button" [routerLink]="['/danka', danka.id, 'family-new']"
- [queryParams]="{relationMode: 'spouse', baseFamilyId: selectedFamily?.id}">
- 配偶者を追加
- </button>
- </div>
- </div>
-
- @if (selectedFamily) {
- <div class="family-tree-diagram">
- <div class="family-tree-svg-container">
-
- <svg #familyTreeSvg width="100%" height="100%" [attr.viewBox]="viewBox"
- preserveAspectRatio="xMidYMid meet">
-
- @for (
- layout of unitLayouts;
- track layout.node.unit.id
- ) {
-
- @for (
- child of layout.node.children;
- track child.unit.id
- ) {
-
- @if (getUnitLayout(child.unit.id); as childLayout) {
-
- <!-- 親から中間点 -->
- <line [attr.x1]="getCenterX(layout)" [attr.y1]="getBottomCenterY(layout)"
- [attr.x2]="getCenterX(layout)" [attr.y2]="getMiddleY(layout, childLayout)" stroke="black"
- stroke-width="2" />
-
- <!-- 横線 -->
- <line [attr.x1]="getCenterX(layout)" [attr.y1]="getMiddleY(layout, childLayout)"
- [attr.x2]="getCenterX(childLayout)" [attr.y2]="getMiddleY(layout, childLayout)" stroke="black"
- stroke-width="2" />
-
- <!-- 子へ -->
- <line [attr.x1]="getCenterX(childLayout)" [attr.y1]="getMiddleY(layout, childLayout)"
- [attr.x2]="getCenterX(childLayout)" [attr.y2]="getTopCenterY(childLayout)" stroke="black"
- stroke-width="2" />
-
- }
-
- }
-
- }
-
- @for (layout of unitLayouts; track layout.node.unit.id) {
-
- <!-- 夫婦線 -->
- @if (layout.node.unit.husband && layout.node.unit.wife) {
- <line [attr.x1]="layout.x + PERSON_WIDTH" [attr.y1]="layout.y + PERSON_HEIGHT / 2"
- [attr.x2]="layout.x + PERSON_WIDTH + SPOUSE_GAP" [attr.y2]="layout.y + PERSON_HEIGHT / 2"
- stroke="red" stroke-width="2" />
- }
-
- <!-- ========================= -->
- <!-- 夫 -->
- <!-- ========================= -->
- @if (layout.node.unit.husband) {
-
- <rect [attr.x]="getHusbandX(layout)" [attr.y]="layout.y" [attr.width]="PERSON_WIDTH"
- [attr.height]="PERSON_HEIGHT" fill="#dbeafe"
- [attr.stroke]="selectedFamily?.id === layout.node.unit.husband?.id ? '#2563eb' : 'black'"
- class="family-node" (click)="selectFamily(layout.node.unit.husband!)" />
-
- <!-- 右:名前(基準) -->
- <text [attr.x]="getHusbandTextX(layout)" [attr.y]="layout.y + 15"
- style="writing-mode: vertical-rl; text-orientation: upright;" class="family-text"
- (click)="selectFamily(layout.node.unit.husband!)">
- {{ layout.node.unit.husband.name }}
- </text>
-
- <!-- 中央:没年月日(名前の左) -->
- @if (getDeathWareki(layout.node.unit.husband)) {
-
- <text [attr.x]="getHusbandTextX(layout) - 26" [attr.y]="getDeathTextY(layout, getDeathWareki(layout.node.unit.husband))"
- dominant-baseline="text-after-edge" style="writing-mode: vertical-rl; text-orientation: upright;"
- [attr.font-size]="DEATH_FONT_SIZE">
- {{ getDeathWareki(layout.node.unit.husband) }}
- </text>
-
- }
-
- <!-- 左:享年 -->
- @if (getAgeAtDeathText(layout.node.unit.husband)) {
-
- <text [attr.x]="getHusbandTextX(layout) - 40" [attr.y]="getDeathTextY(layout, getAgeAtDeathText(layout.node.unit.husband))"
- dominant-baseline="text-after-edge" style="writing-mode: vertical-rl; text-orientation: upright;"
- [attr.font-size]="DEATH_FONT_SIZE">
- {{ getAgeAtDeathText(layout.node.unit.husband) }}
- </text>
-
- }
-
- }
-
- <!-- ========================= -->
- <!-- 妻 -->
- <!-- ========================= -->
- @if (layout.node.unit.wife) {
-
- <rect [attr.x]="getWifeX(layout)" [attr.y]="layout.y" [attr.width]="PERSON_WIDTH"
- [attr.height]="PERSON_HEIGHT" fill="#fde2e2"
- [attr.stroke]="selectedFamily?.id === layout.node.unit.wife?.id ? '#dc2626' : 'black'"
- class="family-node" (click)="selectFamily(layout.node.unit.wife!)" />
-
- <!-- 右:名前 -->
- <text [attr.x]="getWifeTextX(layout)" [attr.y]="layout.y + 15"
- style="writing-mode: vertical-rl; text-orientation: upright;" class="family-text"
- (click)="selectFamily(layout.node.unit.wife!)">
- {{ layout.node.unit.wife.name }}
- </text>
-
- <!-- 中央:没年月日 -->
- @if (getDeathWareki(layout.node.unit.wife)) {
-
- <text [attr.x]="getWifeTextX(layout) - 26" [attr.y]="getDeathTextY(layout, getDeathWareki(layout.node.unit.wife))"
- dominant-baseline="text-after-edge" style="writing-mode: vertical-rl; text-orientation: upright;"
- [attr.font-size]="DEATH_FONT_SIZE">
- {{ getDeathWareki(layout.node.unit.wife) }}
- </text>
-
- }
-
- <!-- 左:享年 -->
- @if (getAgeAtDeathText(layout.node.unit.wife)) {
-
- <text [attr.x]="getWifeTextX(layout) - 40" [attr.y]="getDeathTextY(layout, getAgeAtDeathText(layout.node.unit.wife))"
- dominant-baseline="text-after-edge" style="writing-mode: vertical-rl; text-orientation: upright;"
- [attr.font-size]="DEATH_FONT_SIZE">
- {{ getAgeAtDeathText(layout.node.unit.wife) }}
- </text>
-
- }
-
- }
-
- }
-
- </svg>
-
- </div>
- </div>
- <div class="family-tree-member-list">
- <p class="member-list-title">人物一覧</p>
-
- <div class="member-chip-list">
- @for (family of families; track family.id) {
- <button type="button" class="member-chip" [class.active]="selectedFamily.id === family.id"
- (click)="selectFamily(family)">
- {{ family.name }}
- </button>
- }
- </div>
- </div>
- } @else {
- <p class="empty-family-message">
- 人物カードを選択してください。
- </p>
- }
- </section>
-
- <aside class="family-tree-side-panel">
- <h3>選択中の人物情報</h3>
-
- @if (selectedFamily) {
- <div class="selected-person-card">
- <p class="selected-person-name">
- {{ selectedFamily.name }}
- </p>
-
- <p class="selected-person-sub">
- {{ selectedFamily.furigana || 'ふりがな未登録' }}
- </p>
- </div>
-
- <div class="selected-info-list">
- <div class="selected-info-row">
- <span>続柄</span>
- <strong>{{ selectedFamily.relationship || '未登録' }}</strong>
- </div>
-
- <div class="selected-info-row">
- <span>生年月日</span>
- <strong>{{ selectedFamily.birthDate || '未登録' }}</strong>
- </div>
-
- <div class="selected-info-row">
- <span>父</span>
- <strong>{{ getFather(selectedFamily)?.name || '未登録' }}</strong>
- </div>
-
- <div class="selected-info-row">
- <span>母</span>
- <strong>{{ getMother(selectedFamily)?.name || '未登録' }}</strong>
- </div>
-
- <div class="selected-info-row">
- <span>配偶者</span>
- <strong>{{ getSpouse(selectedFamily)?.name || '未登録' }}</strong>
- </div>
-
- <div class="selected-info-row children-row">
- <span>子</span>
- <strong>
- @if (getChildren(selectedFamily).length > 0) {
- @for (child of getChildren(selectedFamily); track child.id) {
- <span class="child-name">
- {{ child.name }}
- </span>
- }
- } @else {
- 未登録
- }
- </strong>
- </div>
- </div>
-
- <section class="marriage-summary-panel">
- <h4>配偶関係</h4>
-
- <div class="marriage-summary-block">
- <p class="marriage-summary-label">現在の配偶者</p>
-
- @if (getCurrentMarriage(selectedFamily); as currentMarriage) {
- @if (getMarriagePartner(currentMarriage, selectedFamily); as currentPartner) {
- <button type="button" class="marriage-person-button" (click)="selectFamily(currentPartner)">
- {{ currentPartner.name }}
- </button>
- } @else {
- <p class="marriage-empty-text">未登録</p>
- }
- } @else {
- <p class="marriage-empty-text">未登録</p>
- }
- </div>
-
- <div class="marriage-summary-block">
- <p class="marriage-summary-label">過去の配偶者</p>
-
- @if (getPastMarriages(selectedFamily).length > 0) {
- <div class="marriage-history-list">
- @for (relation of getPastMarriages(selectedFamily); track relation.id) {
- @if (getMarriagePartner(relation, selectedFamily); as pastPartner) {
- <button type="button" class="marriage-person-button secondary" (click)="selectFamily(pastPartner)">
- <span>{{ pastPartner.name }}</span>
- <small>{{ getMarriageStatusLabel(relation.status) }}</small>
- </button>
- }
- }
- </div>
- } @else {
- <p class="marriage-empty-text">未登録</p>
- }
- </div>
- </section>
-
- <div class="selected-person-actions">
- <a class="selected-person-button"
- [routerLink]="['/danka', danka.id, 'family', selectedFamily.id, 'edit']">
- 個人情報を編集
- </a>
-
- <button type="button" class="selected-person-button secondary" (click)="selectedTab = 'kakocho'">
- 過去帳を確認
- </button>
- </div>
- } @else {
- <p class="empty-family-message">
- 人物カードを選択してください。
- </p>
- }
- </aside>
- </div>
- } @else {
- <div class="empty-family-message">
- 登録されている家族情報はありません。
- </div>
- }
- </section>
- }
- } @else {
- <p class="empty-family-message">
- 檀家情報が見つかりませんでした。
- </p>
- }
- </section>
- </main>
- </div>
|