Implement debtors prison features across the application: Enhance FalukantController to include debtors prison logic in various service methods. Update FalukantService to manage debtors prison state and integrate it into user data retrieval. Modify frontend components, including DashboardWidget, StatusBar, and BankView, to display debtors prison status and warnings. Add localization for debtors prison messages in English, German, and Spanish, ensuring clarity in user notifications and actions.

This commit is contained in:
Torsten Schulz (local)
2026-03-23 11:59:59 +01:00
parent f2343098d2
commit 9b88a98a20
19 changed files with 1643 additions and 102 deletions

View File

@@ -9,7 +9,24 @@
</div>
</section>
<div v-if="falukantUser?.character" class="imagecontainer">
<section
v-if="falukantUser?.debtorsPrison?.active"
class="falukant-debt-warning surface-card"
:class="{ 'is-prison': falukantUser?.debtorsPrison?.inDebtorsPrison }"
>
<strong>
{{ falukantUser?.debtorsPrison?.inDebtorsPrison
? $t('falukant.bank.debtorsPrison.titlePrison')
: $t('falukant.bank.debtorsPrison.titleWarning') }}
</strong>
<p>
{{ falukantUser?.debtorsPrison?.inDebtorsPrison
? $t('falukant.bank.debtorsPrison.descriptionPrison')
: $t('falukant.bank.debtorsPrison.descriptionWarning') }}
</p>
</section>
<div v-if="falukantUser?.character && !falukantUser?.debtorsPrison?.inDebtorsPrison" class="imagecontainer">
<div :style="getAvatarStyle" class="avatar"></div>
<div class="house-with-character">
<div :style="getHouseStyle" class="house"></div>
@@ -23,6 +40,16 @@
</div>
</div>
<div v-else-if="falukantUser?.character && falukantUser?.debtorsPrison?.inDebtorsPrison" class="imagecontainer imagecontainer--prison">
<div class="debtors-prison-visual" aria-hidden="true">
<div class="debtors-prison-visual__moon"></div>
<div class="debtors-prison-visual__tower"></div>
<div class="debtors-prison-visual__bars debtors-prison-visual__bars--left"></div>
<div class="debtors-prison-visual__bars debtors-prison-visual__bars--right"></div>
<div class="debtors-prison-visual__ground"></div>
</div>
</div>
<section v-if="falukantUser?.character" class="falukant-summary-grid">
<article class="summary-card surface-card">
<span class="summary-card__label">{{ $t('falukant.overview.metadata.certificate') }}</span>
@@ -44,6 +71,15 @@
<strong>{{ stockEntryCount }}</strong>
<p>Verdichteter Blick auf Warenbestand über alle Regionen.</p>
</article>
<article v-if="falukantUser?.debtorsPrison?.active" class="summary-card surface-card">
<span class="summary-card__label">{{ $t('falukant.bank.debtorsPrison.creditworthiness') }}</span>
<strong>{{ falukantUser.debtorsPrison.creditworthiness }}</strong>
<p>
{{ falukantUser.debtorsPrison.nextForcedAction
? $t(`falukant.bank.debtorsPrison.actions.${falukantUser.debtorsPrison.nextForcedAction}`)
: $t('falukant.bank.debtorsPrison.titleWarning') }}
</p>
</article>
</section>
<section v-if="falukantUser?.character" class="falukant-routine-grid">
@@ -357,6 +393,7 @@ export default {
this.socket.off("falukantUpdateStatus");
this.socket.off("falukantUpdateFamily");
this.socket.off("falukantUpdateChurch");
this.socket.off("falukantUpdateDebt");
this.socket.off("falukantUpdateProductionCertificate");
this.socket.off("children_update");
this.socket.off("falukantBranchUpdate");
@@ -376,6 +413,9 @@ export default {
this.socket.on("falukantUpdateChurch", (data) => {
this.handleEvent({ event: 'falukantUpdateChurch', ...data });
});
this.socket.on("falukantUpdateDebt", (data) => {
this.handleEvent({ event: 'falukantUpdateDebt', ...data });
});
this.socket.on("falukantUpdateProductionCertificate", (data) => {
this.handleEvent({ event: 'falukantUpdateProductionCertificate', ...data });
});
@@ -446,6 +486,7 @@ export default {
case 'falukantUpdateStatus':
case 'falukantUpdateFamily':
case 'falukantUpdateChurch':
case 'falukantUpdateDebt':
case 'falukantUpdateProductionCertificate':
case 'children_update':
case 'falukantBranchUpdate':
@@ -579,6 +620,23 @@ export default {
color: var(--color-text-secondary);
}
.falukant-debt-warning {
margin-bottom: 16px;
padding: 16px 18px;
border: 1px solid rgba(180, 120, 40, 0.32);
background: linear-gradient(180deg, rgba(255, 244, 223, 0.95), rgba(255, 250, 239, 0.98));
}
.falukant-debt-warning.is-prison {
border-color: rgba(146, 57, 40, 0.4);
background: linear-gradient(180deg, rgba(255, 232, 225, 0.96), rgba(255, 245, 241, 0.98));
}
.falukant-debt-warning p {
margin: 6px 0 0;
color: var(--color-text-secondary);
}
.falukant-summary-grid,
.falukant-routine-grid {
display: grid;
@@ -694,6 +752,101 @@ export default {
z-index: 0;
}
.imagecontainer--prison {
min-height: 320px;
}
.debtors-prison-visual {
position: relative;
width: min(100%, 540px);
height: 320px;
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
overflow: hidden;
background:
radial-gradient(circle at 18% 22%, rgba(255, 233, 167, 0.95) 0, rgba(255, 233, 167, 0.95) 10%, rgba(255, 233, 167, 0) 11%),
linear-gradient(180deg, #273149 0%, #31476b 42%, #6d5953 42%, #6d5953 100%);
box-shadow: var(--shadow-soft);
}
.debtors-prison-visual__moon {
position: absolute;
top: 42px;
left: 72px;
width: 38px;
height: 38px;
border-radius: 50%;
background: rgba(255, 241, 194, 0.9);
box-shadow: 0 0 24px rgba(255, 241, 194, 0.5);
}
.debtors-prison-visual__tower {
position: absolute;
left: 50%;
bottom: 54px;
width: 160px;
height: 190px;
transform: translateX(-50%);
border-radius: 18px 18px 10px 10px;
background:
linear-gradient(180deg, #8c8a86 0%, #6f6a64 100%);
box-shadow: inset 0 0 0 2px rgba(53, 49, 45, 0.18);
}
.debtors-prison-visual__tower::before {
content: '';
position: absolute;
top: -26px;
left: 18px;
width: 124px;
height: 34px;
border-radius: 10px 10px 0 0;
background:
repeating-linear-gradient(90deg, #7d786f 0, #7d786f 18px, #646057 18px, #646057 26px);
}
.debtors-prison-visual__tower::after {
content: '';
position: absolute;
left: 50%;
bottom: 0;
width: 42px;
height: 88px;
transform: translateX(-50%);
border-radius: 18px 18px 0 0;
background: #40362f;
box-shadow: inset 0 0 0 2px rgba(17, 13, 11, 0.22);
}
.debtors-prison-visual__bars {
position: absolute;
top: 116px;
width: 34px;
height: 54px;
border-radius: 8px;
background:
repeating-linear-gradient(90deg, rgba(33, 31, 29, 0.85) 0, rgba(33, 31, 29, 0.85) 5px, transparent 5px, transparent 11px);
}
.debtors-prison-visual__bars--left {
left: calc(50% - 54px);
}
.debtors-prison-visual__bars--right {
right: calc(50% - 54px);
}
.debtors-prison-visual__ground {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 64px;
background:
linear-gradient(180deg, rgba(72, 57, 51, 0.2), rgba(72, 57, 51, 0.42)),
repeating-linear-gradient(90deg, #756357 0, #756357 18px, #6d5a4f 18px, #6d5a4f 30px);
}
.avatar {
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);