fix(loyalty): translate transaction types + notes on card detail page
Some checks failed
Some checks failed
Card detail transaction history now shows translated transaction type labels and system-generated notes. Uses server-rendered labels object (same pattern as terminal) to avoid async i18n flicker. - Transaction types: server-rendered txLabels lookup (all 11 types) - Notes: txNotes lookup maps English DB strings to translated text (e.g., "Welcome bonus on enrollment" → "Bonus de bienvenue...") - Added welcome_bonus_note key to all 4 locales Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -190,7 +190,8 @@
|
|||||||
"points_adjustment": "Punkte angepasst",
|
"points_adjustment": "Punkte angepasst",
|
||||||
"points_expired": "Punkte verfallen",
|
"points_expired": "Punkte verfallen",
|
||||||
"card_deactivated": "Deaktiviert",
|
"card_deactivated": "Deaktiviert",
|
||||||
"reward_redeemed": "Prämie eingelöst"
|
"reward_redeemed": "Prämie eingelöst",
|
||||||
|
"welcome_bonus_note": "Willkommensbonus bei Anmeldung"
|
||||||
},
|
},
|
||||||
"shared": {
|
"shared": {
|
||||||
"analytics": {
|
"analytics": {
|
||||||
|
|||||||
@@ -194,7 +194,8 @@
|
|||||||
"points_adjustment": "Points Adjusted",
|
"points_adjustment": "Points Adjusted",
|
||||||
"points_expired": "Points Expired",
|
"points_expired": "Points Expired",
|
||||||
"card_deactivated": "Deactivated",
|
"card_deactivated": "Deactivated",
|
||||||
"reward_redeemed": "Reward Redeemed"
|
"reward_redeemed": "Reward Redeemed",
|
||||||
|
"welcome_bonus_note": "Welcome bonus on enrollment"
|
||||||
},
|
},
|
||||||
"shared": {
|
"shared": {
|
||||||
"analytics": {
|
"analytics": {
|
||||||
|
|||||||
@@ -190,7 +190,8 @@
|
|||||||
"points_adjustment": "Points ajustés",
|
"points_adjustment": "Points ajustés",
|
||||||
"points_expired": "Points expirés",
|
"points_expired": "Points expirés",
|
||||||
"card_deactivated": "Désactivé",
|
"card_deactivated": "Désactivé",
|
||||||
"reward_redeemed": "Récompense échangée"
|
"reward_redeemed": "Récompense échangée",
|
||||||
|
"welcome_bonus_note": "Bonus de bienvenue à l'inscription"
|
||||||
},
|
},
|
||||||
"shared": {
|
"shared": {
|
||||||
"analytics": {
|
"analytics": {
|
||||||
|
|||||||
@@ -190,7 +190,8 @@
|
|||||||
"points_adjustment": "Punkten ugepasst",
|
"points_adjustment": "Punkten ugepasst",
|
||||||
"points_expired": "Punkten ofgelaf",
|
"points_expired": "Punkten ofgelaf",
|
||||||
"card_deactivated": "Deaktivéiert",
|
"card_deactivated": "Deaktivéiert",
|
||||||
"reward_redeemed": "Belounung agelées"
|
"reward_redeemed": "Belounung agelées",
|
||||||
|
"welcome_bonus_note": "Wëllkommsbonus bei der Umeldung"
|
||||||
},
|
},
|
||||||
"shared": {
|
"shared": {
|
||||||
"analytics": {
|
"analytics": {
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ function storeLoyaltyCardDetail() {
|
|||||||
card: null,
|
card: null,
|
||||||
transactions: [],
|
transactions: [],
|
||||||
pagination: { page: 1, per_page: 20, total: 0 },
|
pagination: { page: 1, per_page: 20, total: 0 },
|
||||||
|
txLabels: window._cardDetailLabels?.txLabels || {},
|
||||||
|
txNotes: window._cardDetailLabels?.txNotes || {},
|
||||||
|
|
||||||
loading: false,
|
loading: false,
|
||||||
error: null,
|
error: null,
|
||||||
|
|||||||
@@ -161,13 +161,13 @@
|
|||||||
'text-green-700 bg-green-100 dark:bg-green-700 dark:text-green-100': tx.points_delta > 0,
|
'text-green-700 bg-green-100 dark:bg-green-700 dark:text-green-100': tx.points_delta > 0,
|
||||||
'text-orange-700 bg-orange-100 dark:bg-orange-700 dark:text-orange-100': tx.points_delta < 0
|
'text-orange-700 bg-orange-100 dark:bg-orange-700 dark:text-orange-100': tx.points_delta < 0
|
||||||
}"
|
}"
|
||||||
x-text="tx.transaction_type.replace(/_/g, ' ')"></span>
|
x-text="txLabels[tx.transaction_type] || tx.transaction_type.replace(/_/g, ' ')"></span>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-4 py-3 text-sm font-medium"
|
<td class="px-4 py-3 text-sm font-medium"
|
||||||
:class="tx.points_delta > 0 ? 'text-green-600' : 'text-orange-600'"
|
:class="tx.points_delta > 0 ? 'text-green-600' : 'text-orange-600'"
|
||||||
x-text="(tx.points_delta > 0 ? '+' : '') + formatNumber(tx.points_delta)"></td>
|
x-text="(tx.points_delta > 0 ? '+' : '') + formatNumber(tx.points_delta)"></td>
|
||||||
<td class="px-4 py-3 text-sm" x-text="tx.store_name || '-'"></td>
|
<td class="px-4 py-3 text-sm" x-text="tx.store_name || '-'"></td>
|
||||||
<td class="px-4 py-3 text-sm text-gray-500" x-text="tx.notes || '-'"></td>
|
<td class="px-4 py-3 text-sm text-gray-500" x-text="txNotes[tx.notes] || tx.notes || '-'"></td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -179,5 +179,26 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_scripts %}
|
{% block extra_scripts %}
|
||||||
|
<script>
|
||||||
|
// Server-rendered transaction type labels + system note translations
|
||||||
|
window._cardDetailLabels = {
|
||||||
|
txLabels: {
|
||||||
|
card_created: {{ _('loyalty.transactions.card_created')|tojson }},
|
||||||
|
welcome_bonus: {{ _('loyalty.transactions.welcome_bonus')|tojson }},
|
||||||
|
stamp_earned: {{ _('loyalty.transactions.stamp_earned')|tojson }},
|
||||||
|
stamp_redeemed: {{ _('loyalty.transactions.stamp_redeemed')|tojson }},
|
||||||
|
stamp_voided: {{ _('loyalty.transactions.stamp_voided')|tojson }},
|
||||||
|
points_earned: {{ _('loyalty.transactions.points_earned')|tojson }},
|
||||||
|
points_redeemed: {{ _('loyalty.transactions.points_redeemed')|tojson }},
|
||||||
|
points_voided: {{ _('loyalty.transactions.points_voided')|tojson }},
|
||||||
|
points_adjustment: {{ _('loyalty.transactions.points_adjustment')|tojson }},
|
||||||
|
points_expired: {{ _('loyalty.transactions.points_expired')|tojson }},
|
||||||
|
reward_redeemed: {{ _('loyalty.transactions.reward_redeemed')|tojson }},
|
||||||
|
},
|
||||||
|
txNotes: {
|
||||||
|
"Welcome bonus on enrollment": {{ _('loyalty.transactions.welcome_bonus_note')|tojson }},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<script defer src="{{ url_for('loyalty_static', path='store/js/loyalty-card-detail.js') }}"></script>
|
<script defer src="{{ url_for('loyalty_static', path='store/js/loyalty-card-detail.js') }}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user