Refactor backend CORS settings to include default origins and improve error handling in chat services: Introduce dynamic CORS origin handling, enhance RabbitMQ message sending with fallback mechanisms, and update WebSocket service to manage pending messages. Update UI components for better accessibility and responsiveness, including adjustments to dialog and navigation elements. Enhance styling for improved user experience across various components.
This commit is contained in:
@@ -1,11 +1,36 @@
|
||||
<template>
|
||||
<div class="contenthidden">
|
||||
<div class="contentscroll">
|
||||
<div class="contentscroll match3-view">
|
||||
<!-- Spiel-Titel -->
|
||||
<div class="game-title">
|
||||
<section class="game-title surface-card">
|
||||
<span class="game-title__eyebrow">Minispiele</span>
|
||||
<h1>{{ $t('minigames.match3.title') }}</h1>
|
||||
<p>{{ $t('minigames.match3.campaignDescription') }}</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="play-focus surface-card">
|
||||
<div class="play-focus__main">
|
||||
<span class="play-focus__eyebrow">Naechster Schritt</span>
|
||||
<h2>{{ playFocusTitle }}</h2>
|
||||
<p>{{ playFocusDescription }}</p>
|
||||
</div>
|
||||
<div class="play-focus__stats">
|
||||
<span class="play-focus__pill">Level {{ currentLevel }}</span>
|
||||
<span class="play-focus__pill">{{ completedObjectivesCount }}/{{ totalObjectivesCount || 0 }} Ziele</span>
|
||||
<span class="play-focus__pill">{{ safeMovesLeft }} Zuege uebrig</span>
|
||||
</div>
|
||||
<div class="play-focus__actions">
|
||||
<button class="btn btn-primary" @click="isPaused ? resumeGame() : pauseGame()">
|
||||
{{ isPaused ? $t('minigames.match3.resume') : $t('minigames.match3.pause') }}
|
||||
</button>
|
||||
<button class="btn btn-secondary" @click="toggleLevelDescription">
|
||||
{{ levelDescriptionExpanded ? 'Ziele einklappen' : 'Ziele anzeigen' }}
|
||||
</button>
|
||||
<button class="btn btn-secondary" @click="restartLevel">
|
||||
{{ $t('minigames.match3.restartLevel') }}
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Kampagnen-Status -->
|
||||
<div class="game-layout">
|
||||
@@ -45,13 +70,13 @@
|
||||
|
||||
<div class="game-content">
|
||||
<!-- Verbleibende Züge -->
|
||||
<div class="moves-left-display">
|
||||
<div class="moves-left-display surface-card">
|
||||
<span class="moves-left-label">{{ $t('minigames.match3.movesLeft') }}:</span>
|
||||
<span class="moves-left-value">{{ safeMovesLeft }}</span>
|
||||
</div>
|
||||
|
||||
<!-- Level-Info -->
|
||||
<div class="level-info-card" v-if="currentLevelData">
|
||||
<div class="level-info-card surface-card" v-if="currentLevelData">
|
||||
<div class="level-header">
|
||||
<div class="level-header-content">
|
||||
<h3 class="level-title">
|
||||
@@ -6010,6 +6035,42 @@ export default {
|
||||
},
|
||||
safeMovesLeft() {
|
||||
return this.movesLeft || 0;
|
||||
},
|
||||
totalObjectivesCount() {
|
||||
return this.currentLevelData?.objectives?.length || 0;
|
||||
},
|
||||
completedObjectivesCount() {
|
||||
if (!this.currentLevelData?.objectives?.length) {
|
||||
return 0;
|
||||
}
|
||||
return this.currentLevelData.objectives.filter((objective) => objective.completed).length;
|
||||
},
|
||||
nextPendingObjective() {
|
||||
return this.currentLevelData?.objectives?.find((objective) => !objective.completed) || null;
|
||||
},
|
||||
playFocusTitle() {
|
||||
if (this.isPaused) {
|
||||
return 'Spiel ist pausiert';
|
||||
}
|
||||
if (!this.currentLevelData) {
|
||||
return 'Level wird vorbereitet';
|
||||
}
|
||||
if (this.nextPendingObjective) {
|
||||
return this.nextPendingObjective.description || 'Aktuelles Ziel abschliessen';
|
||||
}
|
||||
return 'Level sauber zu Ende spielen';
|
||||
},
|
||||
playFocusDescription() {
|
||||
if (this.isPaused) {
|
||||
return 'Setze das Level fort oder starte es kontrolliert neu, ohne den aktuellen Kontext zu verlieren.';
|
||||
}
|
||||
if (!this.currentLevelData) {
|
||||
return 'Sobald das Level geladen ist, erscheinen hier das naechste Ziel und die passende Hauptaktion.';
|
||||
}
|
||||
if (this.nextPendingObjective) {
|
||||
return `Konzentriere dich zuerst auf dieses Ziel. Bereits erledigt: ${this.completedObjectivesCount} von ${this.totalObjectivesCount}.`;
|
||||
}
|
||||
return 'Alle sichtbaren Ziele sind erledigt. Jetzt zaehlt nur noch der saubere Abschluss des Levels.';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6019,26 +6080,94 @@ export default {
|
||||
/* Minimalistischer Style - nur für Match3Game */
|
||||
/* Verwendet globale Scroll-Klassen: .contenthidden und .contentscroll */
|
||||
|
||||
.match3-view {
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
|
||||
.game-title {
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
padding-top: 20px;
|
||||
margin: 16px auto 30px;
|
||||
max-width: 980px;
|
||||
padding: 28px;
|
||||
background: linear-gradient(135deg, rgba(255, 247, 233, 0.98), rgba(245, 237, 225, 0.95));
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-lg);
|
||||
box-shadow: var(--shadow-soft);
|
||||
}
|
||||
|
||||
.game-title__eyebrow {
|
||||
display: inline-flex;
|
||||
margin-bottom: 10px;
|
||||
padding: 4px 10px;
|
||||
border-radius: var(--radius-pill);
|
||||
background: var(--color-primary-soft);
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.game-title h1 {
|
||||
margin: 0 0 10px 0;
|
||||
font-size: 2rem;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.game-title p {
|
||||
margin: 0;
|
||||
font-size: 1.1rem;
|
||||
color: #666;
|
||||
color: var(--color-text-secondary);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.play-focus {
|
||||
display: grid;
|
||||
gap: 14px;
|
||||
max-width: 980px;
|
||||
margin: 0 auto 20px;
|
||||
padding: 20px 24px;
|
||||
}
|
||||
|
||||
.play-focus__eyebrow {
|
||||
display: inline-flex;
|
||||
margin-bottom: 4px;
|
||||
color: var(--color-text-muted);
|
||||
font-size: 0.76rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.play-focus h2 {
|
||||
margin: 0 0 8px;
|
||||
font-size: 1.35rem;
|
||||
}
|
||||
|
||||
.play-focus p {
|
||||
margin: 0;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.play-focus__stats,
|
||||
.play-focus__actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.play-focus__pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 34px;
|
||||
padding: 0 12px;
|
||||
border-radius: 999px;
|
||||
background: rgba(248, 162, 43, 0.12);
|
||||
color: #8a5411;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* Spiel-Layout */
|
||||
.game-layout {
|
||||
display: flex;
|
||||
@@ -6062,12 +6191,12 @@ export default {
|
||||
|
||||
/* Verbleibende Züge Anzeige */
|
||||
.moves-left-display {
|
||||
background: white;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 5px;
|
||||
background: rgba(255, 251, 246, 0.96);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 8px 14px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
box-shadow: var(--shadow-soft);
|
||||
text-align: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -6078,7 +6207,7 @@ export default {
|
||||
.moves-left-label {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.moves-left-value {
|
||||
@@ -6089,17 +6218,17 @@ export default {
|
||||
|
||||
/* Statistik-Bereich */
|
||||
.stats-card {
|
||||
background: white;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 5px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
background: rgba(255, 251, 246, 0.96);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 8px;
|
||||
box-shadow: var(--shadow-soft);
|
||||
}
|
||||
|
||||
.stats-header {
|
||||
cursor: pointer;
|
||||
padding: 8px;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
margin-bottom: 10px;
|
||||
user-select: none;
|
||||
transition: background-color 0.2s ease;
|
||||
@@ -6107,7 +6236,7 @@ export default {
|
||||
}
|
||||
|
||||
.stats-header:hover {
|
||||
background-color: #f8f9fa;
|
||||
background-color: rgba(248, 162, 43, 0.08);
|
||||
}
|
||||
|
||||
.stats-header-content {
|
||||
@@ -6121,7 +6250,7 @@ export default {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
color: var(--color-text-primary);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@@ -6174,7 +6303,7 @@ export default {
|
||||
|
||||
.stat-label {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
/* Statistik-Werte Farben */
|
||||
@@ -6185,12 +6314,12 @@ export default {
|
||||
|
||||
/* Level-Info */
|
||||
.level-info-card {
|
||||
background: white;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 5px;
|
||||
background: rgba(255, 251, 246, 0.96);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 8px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
box-shadow: var(--shadow-soft);
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
}
|
||||
@@ -6198,7 +6327,7 @@ export default {
|
||||
.level-header {
|
||||
cursor: pointer;
|
||||
padding: 8px;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
margin-bottom: 10px;
|
||||
user-select: none;
|
||||
transition: background-color 0.2s ease;
|
||||
@@ -6206,7 +6335,7 @@ export default {
|
||||
}
|
||||
|
||||
.level-header:hover {
|
||||
background-color: #f8f9fa;
|
||||
background-color: rgba(248, 162, 43, 0.08);
|
||||
}
|
||||
|
||||
.level-header-content {
|
||||
@@ -6220,7 +6349,7 @@ export default {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
color: var(--color-text-primary);
|
||||
flex-grow: 1;
|
||||
text-align: left;
|
||||
pointer-events: none;
|
||||
@@ -6233,7 +6362,7 @@ export default {
|
||||
.level-info-card p {
|
||||
margin: 0 0 15px 0;
|
||||
text-align: left;
|
||||
color: #666;
|
||||
color: var(--color-text-secondary);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
@@ -6248,8 +6377,8 @@ export default {
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
padding: 8px;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 4px;
|
||||
background-color: rgba(255, 255, 255, 0.64);
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
.objective-icon {
|
||||
@@ -6265,7 +6394,7 @@ export default {
|
||||
.objective-progress {
|
||||
margin-left: auto;
|
||||
font-size: 12px;
|
||||
color: #6c757d;
|
||||
color: var(--color-text-muted);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@@ -6273,10 +6402,10 @@ export default {
|
||||
.game-board-container {
|
||||
display: inline-block;
|
||||
padding: 20px;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #ddd;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
background: rgba(255, 251, 246, 0.96);
|
||||
border-radius: var(--radius-lg);
|
||||
border: 1px solid var(--color-border);
|
||||
box-shadow: var(--shadow-soft);
|
||||
margin-bottom: 20px;
|
||||
position: relative; /* Für absolute Positionierung der Animationen */
|
||||
}
|
||||
@@ -6461,6 +6590,17 @@ export default {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
.game-title {
|
||||
margin-top: 12px;
|
||||
padding: 22px 18px;
|
||||
}
|
||||
|
||||
.play-focus {
|
||||
padding: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 10px 20px;
|
||||
@@ -6875,4 +7015,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user