feat(family): enhance family view and character pregnancy handling
All checks were successful
Deploy to production / deploy (push) Successful in 2m48s
All checks were successful
Deploy to production / deploy (push) Successful in 2m48s
- Updated the FalukantCharacter model to include a default scope that excludes pregnancy-related fields for compatibility with older databases. - Implemented a new method in FalukantService to conditionally retrieve pregnancy information based on database schema. - Enhanced the FamilyView component to display a summary navigation for family relationships, including partners, children, and lovers. - Updated internationalization files to include new translations for family-related terms and summaries.
This commit is contained in:
@@ -61,7 +61,12 @@ FalukantCharacter.init(
|
|||||||
tableName: 'character',
|
tableName: 'character',
|
||||||
schema: 'falukant_data',
|
schema: 'falukant_data',
|
||||||
timestamps: true,
|
timestamps: true,
|
||||||
underscored: true}
|
underscored: true,
|
||||||
|
// Spalten erst nach Migration 20260330000000; ohne Exclude würde SELECT/INSERT auf alten DBs fehlschlagen
|
||||||
|
defaultScope: {
|
||||||
|
attributes: { exclude: ['pregnancyDueAt', 'pregnancyFatherCharacterId'] },
|
||||||
|
},
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export default FalukantCharacter;
|
export default FalukantCharacter;
|
||||||
|
|||||||
@@ -3320,11 +3320,31 @@ class FalukantService extends BaseService {
|
|||||||
return { result: 'ok' };
|
return { result: 'ok' };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Liest Schwangerschaft nur wenn DB-Spalten existieren (nach Migration). */
|
||||||
|
async _getCharacterPregnancyOptional(characterId) {
|
||||||
|
try {
|
||||||
|
const rows = await sequelize.query(
|
||||||
|
`SELECT pregnancy_due_at, pregnancy_father_character_id
|
||||||
|
FROM falukant_data."character" WHERE id = :id`,
|
||||||
|
{ replacements: { id: characterId }, type: Sequelize.QueryTypes.SELECT }
|
||||||
|
);
|
||||||
|
const row = rows[0];
|
||||||
|
if (!row?.pregnancy_due_at) return null;
|
||||||
|
return {
|
||||||
|
dueAt: row.pregnancy_due_at,
|
||||||
|
fatherCharacterId: row.pregnancy_father_character_id,
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async getFamily(hashedUserId) {
|
async getFamily(hashedUserId) {
|
||||||
const user = await this.getFalukantUserByHashedId(hashedUserId);
|
const user = await this.getFalukantUserByHashedId(hashedUserId);
|
||||||
if (!user) throw new Error('User not found');
|
if (!user) throw new Error('User not found');
|
||||||
const character = await FalukantCharacter.findOne({ where: { userId: user.id } });
|
const character = await FalukantCharacter.findOne({ where: { userId: user.id } });
|
||||||
if (!character) throw new Error('Character not found for this user');
|
if (!character) throw new Error('Character not found for this user');
|
||||||
|
const pregnancy = await this._getCharacterPregnancyOptional(character.id);
|
||||||
// Load relationships without includes to avoid EagerLoadingError
|
// Load relationships without includes to avoid EagerLoadingError
|
||||||
const relRows = await Relationship.findAll({
|
const relRows = await Relationship.findAll({
|
||||||
where: { character1Id: character.id },
|
where: { character1Id: character.id },
|
||||||
@@ -3519,12 +3539,7 @@ class FalukantService extends BaseService {
|
|||||||
children: children.map(({ _createdAt, ...rest }) => rest),
|
children: children.map(({ _createdAt, ...rest }) => rest),
|
||||||
possiblePartners: [],
|
possiblePartners: [],
|
||||||
possibleLovers: [],
|
possibleLovers: [],
|
||||||
pregnancy: character.pregnancyDueAt
|
pregnancy,
|
||||||
? {
|
|
||||||
dueAt: character.pregnancyDueAt,
|
|
||||||
fatherCharacterId: character.pregnancyFatherCharacterId,
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
};
|
};
|
||||||
const ownAge = calcAge(character.birthdate);
|
const ownAge = calcAge(character.birthdate);
|
||||||
if (ownAge >= 12) {
|
if (ownAge >= 12) {
|
||||||
|
|||||||
@@ -536,6 +536,20 @@
|
|||||||
},
|
},
|
||||||
"family": {
|
"family": {
|
||||||
"title": "Familie",
|
"title": "Familie",
|
||||||
|
"heroIntro": "Beziehungen, Kinder und Entwicklung — unten nach Bereichen geordnet.",
|
||||||
|
"summary": {
|
||||||
|
"partnerChip": "Partner",
|
||||||
|
"childrenChip": "Kinder",
|
||||||
|
"loversChip": "Liebschaften",
|
||||||
|
"proposalsAvailable": "Verlobung möglich",
|
||||||
|
"noPartner": "Kein Partner"
|
||||||
|
},
|
||||||
|
"tabs": {
|
||||||
|
"partner": "Partner & Ehe",
|
||||||
|
"children": "Kinder",
|
||||||
|
"lovers": "Liebschaften"
|
||||||
|
},
|
||||||
|
"tabsAria": "Familienbereiche",
|
||||||
"debtorsPrison": {
|
"debtorsPrison": {
|
||||||
"familyWarning": "Anhaltender Kreditverzug belastet Ehe, Haushalt und Liebschaften.",
|
"familyWarning": "Anhaltender Kreditverzug belastet Ehe, Haushalt und Liebschaften.",
|
||||||
"familyImpact": "Der Schuldturm schadet Ehe, Hausfrieden und der Stabilität von Liebschaften."
|
"familyImpact": "Der Schuldturm schadet Ehe, Hausfrieden und der Stabilität von Liebschaften."
|
||||||
@@ -546,6 +560,7 @@
|
|||||||
},
|
},
|
||||||
"spouse": {
|
"spouse": {
|
||||||
"title": "Beziehung",
|
"title": "Beziehung",
|
||||||
|
"traitsToggle": "Charaktereigenschaften",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"age": "Alter",
|
"age": "Alter",
|
||||||
"status": "Status",
|
"status": "Status",
|
||||||
|
|||||||
@@ -607,6 +607,21 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"family": {
|
"family": {
|
||||||
|
"title": "Family",
|
||||||
|
"heroIntro": "Relationships, children and development — organized by section below.",
|
||||||
|
"summary": {
|
||||||
|
"partnerChip": "Partner",
|
||||||
|
"childrenChip": "Children",
|
||||||
|
"loversChip": "Affairs",
|
||||||
|
"proposalsAvailable": "Betrothal available",
|
||||||
|
"noPartner": "No partner"
|
||||||
|
},
|
||||||
|
"tabs": {
|
||||||
|
"partner": "Partner & marriage",
|
||||||
|
"children": "Children",
|
||||||
|
"lovers": "Affairs"
|
||||||
|
},
|
||||||
|
"tabsAria": "Family sections",
|
||||||
"debtorsPrison": {
|
"debtorsPrison": {
|
||||||
"familyWarning": "Ongoing debt delinquency puts strain on marriage, household and affairs.",
|
"familyWarning": "Ongoing debt delinquency puts strain on marriage, household and affairs.",
|
||||||
"familyImpact": "Debtors' prison damages marriage, household peace and the stability of affairs."
|
"familyImpact": "Debtors' prison damages marriage, household peace and the stability of affairs."
|
||||||
@@ -653,6 +668,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"spouse": {
|
"spouse": {
|
||||||
|
"traitsToggle": "Character traits",
|
||||||
"marriageSatisfaction": "Marriage Satisfaction",
|
"marriageSatisfaction": "Marriage Satisfaction",
|
||||||
"marriageState": "Marriage State",
|
"marriageState": "Marriage State",
|
||||||
"wooing": {
|
"wooing": {
|
||||||
|
|||||||
@@ -517,6 +517,20 @@
|
|||||||
},
|
},
|
||||||
"family": {
|
"family": {
|
||||||
"title": "Familia",
|
"title": "Familia",
|
||||||
|
"heroIntro": "Relaciones, hijos y desarrollo — ordenado por secciones abajo.",
|
||||||
|
"summary": {
|
||||||
|
"partnerChip": "Pareja",
|
||||||
|
"childrenChip": "Hijos",
|
||||||
|
"loversChip": "Relaciones",
|
||||||
|
"proposalsAvailable": "Compromiso posible",
|
||||||
|
"noPartner": "Sin pareja"
|
||||||
|
},
|
||||||
|
"tabs": {
|
||||||
|
"partner": "Pareja y matrimonio",
|
||||||
|
"children": "Hijos",
|
||||||
|
"lovers": "Relaciones"
|
||||||
|
},
|
||||||
|
"tabsAria": "Secciones de familia",
|
||||||
"debtorsPrison": {
|
"debtorsPrison": {
|
||||||
"familyWarning": "La mora continuada perjudica el matrimonio, el hogar y las relaciones.",
|
"familyWarning": "La mora continuada perjudica el matrimonio, el hogar y las relaciones.",
|
||||||
"familyImpact": "La prisión por deudas daña el matrimonio, la paz del hogar y la estabilidad de las relaciones."
|
"familyImpact": "La prisión por deudas daña el matrimonio, la paz del hogar y la estabilidad de las relaciones."
|
||||||
@@ -527,6 +541,7 @@
|
|||||||
},
|
},
|
||||||
"spouse": {
|
"spouse": {
|
||||||
"title": "Relación",
|
"title": "Relación",
|
||||||
|
"traitsToggle": "Rasgos de carácter",
|
||||||
"name": "Nombre",
|
"name": "Nombre",
|
||||||
"age": "Edad",
|
"age": "Edad",
|
||||||
"status": "Estado",
|
"status": "Estado",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<span class="family-kicker">Familie</span>
|
<span class="family-kicker">Familie</span>
|
||||||
<h2>{{ $t('falukant.family.title') }}</h2>
|
<h2>{{ $t('falukant.family.title') }}</h2>
|
||||||
<p>Beziehungen, Kinder und familiäre Entwicklung in einer eigenen Spielweltansicht.</p>
|
<p>{{ $t('falukant.family.heroIntro') }}</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -36,62 +36,116 @@
|
|||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<nav
|
||||||
|
class="family-summary-strip surface-card"
|
||||||
|
role="tablist"
|
||||||
|
:aria-label="$t('falukant.family.tabsAria')"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
role="tab"
|
||||||
|
:aria-selected="familyTab === 'partner'"
|
||||||
|
class="family-summary-chip"
|
||||||
|
:class="{ 'is-active': familyTab === 'partner' }"
|
||||||
|
:title="$t('falukant.family.tabs.partner')"
|
||||||
|
@click="familyTab = 'partner'"
|
||||||
|
>
|
||||||
|
<span class="family-summary-chip__label">{{ $t('falukant.family.summary.partnerChip') }}</span>
|
||||||
|
<span class="family-summary-chip__value">{{ partnerSummaryLine }}</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
role="tab"
|
||||||
|
:aria-selected="familyTab === 'children'"
|
||||||
|
class="family-summary-chip"
|
||||||
|
:class="{ 'is-active': familyTab === 'children' }"
|
||||||
|
:title="$t('falukant.family.tabs.children')"
|
||||||
|
@click="familyTab = 'children'"
|
||||||
|
>
|
||||||
|
<span class="family-summary-chip__label">{{ $t('falukant.family.summary.childrenChip') }}</span>
|
||||||
|
<span class="family-summary-chip__value">{{ children.length }}</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
role="tab"
|
||||||
|
:aria-selected="familyTab === 'lovers'"
|
||||||
|
class="family-summary-chip"
|
||||||
|
:class="{ 'is-active': familyTab === 'lovers' }"
|
||||||
|
:title="$t('falukant.family.tabs.lovers')"
|
||||||
|
@click="familyTab = 'lovers'"
|
||||||
|
>
|
||||||
|
<span class="family-summary-chip__label">{{ $t('falukant.family.summary.loversChip') }}</span>
|
||||||
|
<span class="family-summary-chip__value">{{ lovers.length }}</span>
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-show="familyTab === 'partner'"
|
||||||
|
class="family-tab-panel"
|
||||||
|
role="tabpanel"
|
||||||
|
>
|
||||||
<div class="spouse-section">
|
<div class="spouse-section">
|
||||||
<h3>{{ $t('falukant.family.spouse.title') }}</h3>
|
<h3>{{ $t('falukant.family.spouse.title') }}</h3>
|
||||||
<div v-if="relationships.length > 0" class="relationship-container">
|
<div v-if="relationships.length > 0" class="relationship-container">
|
||||||
<div class="relationship-row">
|
<div class="relationship-row">
|
||||||
<div class="relationship">
|
<div class="relationship">
|
||||||
<table>
|
<dl class="spouse-card__dl">
|
||||||
<tr>
|
<div>
|
||||||
<td>{{ $t('falukant.family.relationships.name') }}</td>
|
<dt>{{ $t('falukant.family.relationships.name') }}</dt>
|
||||||
<td>
|
<dd>
|
||||||
{{ $t('falukant.titles.' + relationships[0].character2.gender + '.' +
|
{{ $t('falukant.titles.' + relationships[0].character2.gender + '.' +
|
||||||
relationships[0].character2.nobleTitle) }}
|
relationships[0].character2.nobleTitle) }}
|
||||||
{{ relationships[0].character2.firstName }}
|
{{ relationships[0].character2.firstName }}
|
||||||
</td>
|
</dd>
|
||||||
</tr>
|
</div>
|
||||||
<tr>
|
<div>
|
||||||
<td>{{ $t('falukant.family.spouse.age') }}</td>
|
<dt>{{ $t('falukant.family.spouse.age') }}</dt>
|
||||||
<td>{{ relationships[0].character2.age }}</td>
|
<dd>{{ relationships[0].character2.age }}</dd>
|
||||||
</tr>
|
</div>
|
||||||
<tr>
|
<div>
|
||||||
<td>{{ $t('falukant.family.spouse.mood') }}</td>
|
<dt>{{ $t('falukant.family.spouse.mood') }}</dt>
|
||||||
<td>{{ relationships[0].character2.mood?.tr ? $t(`falukant.mood.${relationships[0].character2.mood.tr}`) : '—' }}</td>
|
<dd>{{ relationships[0].character2.mood?.tr ? $t(`falukant.mood.${relationships[0].character2.mood.tr}`) : '—' }}</dd>
|
||||||
</tr>
|
</div>
|
||||||
<tr>
|
<div>
|
||||||
<td>{{ $t('falukant.family.spouse.status') }}</td>
|
<dt>{{ $t('falukant.family.spouse.status') }}</dt>
|
||||||
<td>{{ $t('falukant.family.statuses.' + relationships[0].relationshipType) }}</td>
|
<dd>{{ $t('falukant.family.statuses.' + relationships[0].relationshipType) }}</dd>
|
||||||
</tr>
|
</div>
|
||||||
<tr v-if="relationships[0].marriageSatisfaction != null">
|
<div v-if="relationships[0].marriageSatisfaction != null">
|
||||||
<td>{{ $t('falukant.family.spouse.marriageSatisfaction') }}</td>
|
<dt>{{ $t('falukant.family.spouse.marriageSatisfaction') }}</dt>
|
||||||
<td>
|
<dd>
|
||||||
{{ relationships[0].marriageSatisfaction }}
|
{{ relationships[0].marriageSatisfaction }}
|
||||||
<span class="inline-status-pill" :class="`inline-status-pill--${relationships[0].marriageState || 'stable'}`">
|
<span class="inline-status-pill" :class="`inline-status-pill--${relationships[0].marriageState || 'stable'}`">
|
||||||
{{ $t('falukant.family.marriageState.' + (relationships[0].marriageState || 'stable')) }}
|
{{ $t('falukant.family.marriageState.' + (relationships[0].marriageState || 'stable')) }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</dd>
|
||||||
</tr>
|
</div>
|
||||||
<tr v-if="relationships[0].relationshipType === 'wooing'">
|
<div v-if="relationships[0].relationshipType === 'wooing'">
|
||||||
<td>{{ $t('falukant.family.spouse.progress') }}</td>
|
<dt>{{ $t('falukant.family.spouse.progress') }}</dt>
|
||||||
<td>
|
<dd>
|
||||||
<div class="progress">
|
<div class="progress">
|
||||||
<div class="progress-inner" :style="{
|
<div class="progress-inner" :style="{
|
||||||
width: normalizeWooingProgress(relationships[0].progress) + '%',
|
width: normalizeWooingProgress(relationships[0].progress) + '%',
|
||||||
backgroundColor: progressColor(relationships[0].progress)
|
backgroundColor: progressColor(relationships[0].progress)
|
||||||
}"></div>
|
}"></div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</dd>
|
||||||
</tr>
|
</div>
|
||||||
<tr v-if="relationships[0].relationshipType === 'engaged'" colspan="2">
|
</dl>
|
||||||
<button @click="jumpToPartyForm">{{ $t('falukant.family.spouse.jumpToPartyForm')
|
<div v-if="relationships[0].relationshipType === 'engaged'" class="spouse-card__cta">
|
||||||
|
<button type="button" class="button" @click="jumpToPartyForm">{{ $t('falukant.family.spouse.jumpToPartyForm')
|
||||||
}}</button>
|
}}</button>
|
||||||
</tr>
|
</div>
|
||||||
</table>
|
<details
|
||||||
|
v-if="relationships[0].character2.traits?.length"
|
||||||
|
class="spouse-traits"
|
||||||
|
>
|
||||||
|
<summary>{{ $t('falukant.family.spouse.traitsToggle') }}</summary>
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="trait in relationships[0].character2.traits" :key="trait.id">
|
<li v-for="trait in relationships[0].character2.traits" :key="trait.id">
|
||||||
{{ $t(`falukant.character.${trait.tr}`) }}
|
{{ $t(`falukant.character.${trait.tr}`) }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
</details>
|
||||||
</div>
|
</div>
|
||||||
<div class="partner-character-3d">
|
<div class="partner-character-3d">
|
||||||
<Character3D
|
<Character3D
|
||||||
@@ -208,7 +262,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-show="familyTab === 'children'"
|
||||||
|
class="family-tab-panel"
|
||||||
|
role="tabpanel"
|
||||||
|
>
|
||||||
<div class="children-section">
|
<div class="children-section">
|
||||||
<h3>{{ $t('falukant.family.children.title') }}</h3>
|
<h3>{{ $t('falukant.family.children.title') }}</h3>
|
||||||
<div v-if="children && children.length > 0" class="children-container">
|
<div v-if="children && children.length > 0" class="children-container">
|
||||||
@@ -262,7 +322,13 @@
|
|||||||
<p>{{ $t('falukant.family.children.none') }}</p>
|
<p>{{ $t('falukant.family.children.none') }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-show="familyTab === 'lovers'"
|
||||||
|
class="family-tab-panel"
|
||||||
|
role="tabpanel"
|
||||||
|
>
|
||||||
<!-- Liebhaber / Geliebte -->
|
<!-- Liebhaber / Geliebte -->
|
||||||
<div class="lovers-section">
|
<div class="lovers-section">
|
||||||
<h3>{{ $t('falukant.family.lovers.title') }}</h3>
|
<h3>{{ $t('falukant.family.lovers.title') }}</h3>
|
||||||
@@ -369,6 +435,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<ChildDetailsDialog ref="childDetailsDialog" />
|
<ChildDetailsDialog ref="childDetailsDialog" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -417,11 +484,27 @@ export default {
|
|||||||
},
|
},
|
||||||
pregnancy: null,
|
pregnancy: null,
|
||||||
selectedChild: null,
|
selectedChild: null,
|
||||||
pendingFamilyRefresh: null
|
pendingFamilyRefresh: null,
|
||||||
|
familyTab: 'partner',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['socket', 'daemonSocket', 'user'])
|
...mapState(['socket', 'daemonSocket', 'user']),
|
||||||
|
partnerSummaryLine() {
|
||||||
|
if (this.relationships?.length > 0) {
|
||||||
|
const r = this.relationships[0];
|
||||||
|
const c2 = r.character2;
|
||||||
|
const name = c2
|
||||||
|
? `${this.$t(`falukant.titles.${c2.gender}.${c2.nobleTitle}`)} ${c2.firstName}`.trim()
|
||||||
|
: '';
|
||||||
|
const status = this.$t(`falukant.family.statuses.${r.relationshipType}`);
|
||||||
|
return name ? `${name} · ${status}` : status;
|
||||||
|
}
|
||||||
|
if (this.proposals?.length > 0) {
|
||||||
|
return this.$t('falukant.family.summary.proposalsAvailable');
|
||||||
|
}
|
||||||
|
return this.$t('falukant.family.summary.noPartner');
|
||||||
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
socket(newVal, oldVal) {
|
socket(newVal, oldVal) {
|
||||||
@@ -725,26 +808,6 @@ export default {
|
|||||||
return new Intl.NumberFormat(navigator.language, { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(value);
|
return new Intl.NumberFormat(navigator.language, { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(value);
|
||||||
},
|
},
|
||||||
|
|
||||||
getEffect(gift) {
|
|
||||||
const relationship = this.relationships[0];
|
|
||||||
if (!relationship || !relationship.character2) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
const partner = relationship.character2;
|
|
||||||
const currentMoodId = partner.moodId;
|
|
||||||
const moodEntry = gift.moodsAffects.find(ma => ma.mood_id === currentMoodId);
|
|
||||||
const moodValue = moodEntry ? moodEntry.suitability : 0;
|
|
||||||
let highestCharacterValue = 0;
|
|
||||||
// traits ist ein Array von Trait-Objekten mit id und tr
|
|
||||||
for (const trait of partner.traits || []) {
|
|
||||||
const charEntry = gift.charactersAffects.find(ca => ca.trait_id === trait.id);
|
|
||||||
if (charEntry && charEntry.suitability > highestCharacterValue) {
|
|
||||||
highestCharacterValue = charEntry.suitability;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Math.round((moodValue + highestCharacterValue) / 2);
|
|
||||||
},
|
|
||||||
|
|
||||||
async acceptProposal() {
|
async acceptProposal() {
|
||||||
const response = await apiClient.post('/api/falukant/family/acceptmarriageproposal'
|
const response = await apiClient.post('/api/falukant/family/acceptmarriageproposal'
|
||||||
, { proposalId: this.selectedProposalId });
|
, { proposalId: this.selectedProposalId });
|
||||||
@@ -955,6 +1018,116 @@ export default {
|
|||||||
color: var(--color-text-secondary);
|
color: var(--color-text-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.family-summary-strip {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding: 12px 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.family-summary-chip {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 2px;
|
||||||
|
padding: 10px 14px;
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
background: rgba(255, 252, 247, 0.95);
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: left;
|
||||||
|
font: inherit;
|
||||||
|
color: inherit;
|
||||||
|
min-width: 0;
|
||||||
|
flex: 1 1 140px;
|
||||||
|
max-width: 100%;
|
||||||
|
transition: border-color 0.15s ease, box-shadow 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.family-summary-chip:hover {
|
||||||
|
border-color: rgba(248, 162, 43, 0.45);
|
||||||
|
}
|
||||||
|
|
||||||
|
.family-summary-chip.is-active {
|
||||||
|
border-color: rgba(248, 162, 43, 0.65);
|
||||||
|
box-shadow: 0 0 0 1px rgba(248, 162, 43, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.family-summary-chip__label {
|
||||||
|
font-size: 0.72rem;
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.family-summary-chip__value {
|
||||||
|
font-size: 0.92rem;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.35;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
.family-tab-panel {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spouse-card__dl {
|
||||||
|
margin: 0;
|
||||||
|
display: grid;
|
||||||
|
gap: 10px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spouse-card__dl > div {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(7rem, 34%) 1fr;
|
||||||
|
gap: 8px 12px;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spouse-card__dl dt {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
font-size: 0.82rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spouse-card__dl dd {
|
||||||
|
margin: 0;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spouse-card__cta {
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spouse-traits {
|
||||||
|
margin-top: 14px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border: 1px dashed var(--color-border);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
background: rgba(255, 250, 243, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.spouse-traits summary {
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.88rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.spouse-traits ul {
|
||||||
|
margin: 10px 0 0;
|
||||||
|
padding-left: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.spouse-card__dl > div {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.marriage-overview {
|
.marriage-overview {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||||
@@ -1335,17 +1508,6 @@ export default {
|
|||||||
width: 50px;
|
width: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.relationship>table,
|
|
||||||
.relationship>ul {
|
|
||||||
display: inline-block;
|
|
||||||
margin-right: 1em;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.relationship>ul {
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress {
|
.progress {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: #e5e7eb;
|
background-color: #e5e7eb;
|
||||||
|
|||||||
Reference in New Issue
Block a user