Add marriage management features: Implement endpoints for spending time with, gifting to, and reconciling with spouses in the FalukantController. Update UserHouse model to include household tension attributes. Enhance frontend components to manage marriage actions and display household tension details, including localization updates in multiple languages.

This commit is contained in:
Torsten Schulz (local)
2026-03-23 09:34:56 +01:00
parent e23849bee7
commit cd84dc03d5
23 changed files with 1997 additions and 52 deletions

View File

@@ -47,6 +47,9 @@
<button class="button-secondary" :disabled="(userHouse.servantCount || 0) <= 0" @click="dismissServant">
{{ $t('falukant.house.servants.actions.dismiss') }}
</button>
<button class="button-secondary" @click="tidyHousehold">
{{ $t('falukant.house.servants.actions.tidy') }}
</button>
</div>
</div>
@@ -71,6 +74,10 @@
<span class="servant-card__label">{{ $t('falukant.house.servants.householdOrder') }}</span>
<strong>{{ userHouse.householdOrder || 0 }}</strong>
</article>
<article class="servant-card">
<span class="servant-card__label">{{ $t('falukant.family.householdTension.score') }}</span>
<strong>{{ userHouse.householdTensionScore ?? 0 }}</strong>
</article>
<article class="servant-card">
<span class="servant-card__label">{{ $t('falukant.house.servants.staffingState.label') }}</span>
<strong>{{ $t(`falukant.house.servants.staffingState.${servantSummary.staffingState || 'fitting'}`) }}</strong>
@@ -91,6 +98,14 @@
<strong>{{ $t(`falukant.house.servants.orderState.${servantSummary.orderState || 'stable'}`) }}</strong>
</div>
</div>
<div v-if="Array.isArray(userHouse.householdTensionReasonsJson) && userHouse.householdTensionReasonsJson.length > 0" class="servants-reasons">
<span class="servants-reasons__label">{{ $t('falukant.family.householdTension.reasonsLabel') }}</span>
<div class="servants-reasons__list">
<span v-for="reason in userHouse.householdTensionReasonsJson" :key="reason" class="servants-reasons__badge">
{{ $t('falukant.family.householdTension.reasons.' + reason) }}
</span>
</div>
</div>
</section>
<div class="buyable-houses">
@@ -299,6 +314,16 @@ export default {
showError(this, this.$t('falukant.house.servants.actions.payLevelError'));
}
},
async tidyHousehold() {
try {
await apiClient.post('/api/falukant/houses/order');
await this.loadData();
showSuccess(this, this.$t('falukant.house.servants.actions.tidySuccess'));
} catch (err) {
console.error('Error tidying household', err);
showError(this, this.$t('falukant.house.servants.actions.tidyError'));
}
},
handleDaemonMessage(evt) {
try {
const msg = JSON.parse(evt.data);
@@ -344,6 +369,17 @@ export default {
display: flex;
flex-direction: column;
gap: 20px;
/* AppContent gibt dem letzten Kind flex:1 + min-height:0 — sonst schrumpfen
Spalten-Kinder und überlagern sich (z. B. „Dienerschaft“ unter „Kaufe ein Haus“). */
flex: 0 0 auto;
min-height: min-content;
width: 100%;
}
.existing-house,
.servants-panel,
.buyable-houses {
flex-shrink: 0;
}
h2 {
@@ -442,6 +478,34 @@ h2 {
color: var(--color-text-secondary);
}
.servants-reasons {
display: grid;
gap: 8px;
margin-top: 16px;
}
.servants-reasons__label {
color: var(--color-text-secondary);
font-size: 0.88rem;
}
.servants-reasons__list {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.servants-reasons__badge {
display: inline-flex;
align-items: center;
padding: 4px 10px;
border-radius: 999px;
background: rgba(188, 84, 61, 0.12);
color: #9a3c26;
font-size: 0.8rem;
font-weight: 700;
}
.buyable-houses {
display: flex;
flex-direction: column;