From bac6d114a2eaebce59bae84437d2f2fc2661a10f Mon Sep 17 00:00:00 2001 From: Maaxxs <61059039+MaaxxsDev@users.noreply.github.com> Date: Wed, 8 Jul 2026 09:48:59 +0200 Subject: [PATCH] Add a tier number and category label to package cards Inspired by a reference mockup showing a numbered, categorized tier lineup (Einstieg/Upgrade/.../Referenz). Each card now shows its price rank (01, 02...) plus an auto-derived category eyebrow label, computed the same way as the material-tier color system so it needs no extra admin config and scales to any package count. Kept the existing responsive grid rather than switching to a fixed horizontal row, since the fixed layout looks broken for models with only 1-2 packages. Co-Authored-By: Claude Sonnet 5 --- hifi-src/src/i18n/de.js | 1 + hifi-src/src/i18n/en.js | 1 + hifi-src/src/pages/public/ModelPage.jsx | 11 ++++++++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/hifi-src/src/i18n/de.js b/hifi-src/src/i18n/de.js index a8a3ef1..1b7ee48 100644 --- a/hifi-src/src/i18n/de.js +++ b/hifi-src/src/i18n/de.js @@ -155,6 +155,7 @@ export default { productLoading: 'Produkt wird geladen…', requestContact: 'Kontakt anfragen', featuredBadge: 'Empfohlen', + tierLabels: ['Einstieg', 'Upgrade', 'Performance', 'Premium', 'High-End', 'Signature', 'Referenz'], }, leistungen: { metaTitle: 'Leistungen', diff --git a/hifi-src/src/i18n/en.js b/hifi-src/src/i18n/en.js index 965dc18..9506557 100644 --- a/hifi-src/src/i18n/en.js +++ b/hifi-src/src/i18n/en.js @@ -155,6 +155,7 @@ export default { productLoading: 'Loading product…', requestContact: 'Request contact', featuredBadge: 'Recommended', + tierLabels: ['Entry', 'Upgrade', 'Performance', 'Premium', 'High-End', 'Signature', 'Reference'], }, leistungen: { metaTitle: 'Services', diff --git a/hifi-src/src/pages/public/ModelPage.jsx b/hifi-src/src/pages/public/ModelPage.jsx index aa1c804..cac910a 100644 --- a/hifi-src/src/pages/public/ModelPage.jsx +++ b/hifi-src/src/pages/public/ModelPage.jsx @@ -111,6 +111,7 @@ export default function ModelPage() { // oben. Das braucht keine zusaetzliche Admin-Einstellung und passt sich automatisch // an jede Paketanzahl an. const materials = theme === 'dark' ? MATERIALS_DARK : MATERIALS_LIGHT; + const tierLabels = t('modelPage.tierLabels'); const rankById = new Map( [...packages].sort((a, b) => a.total_price - b.total_price).map((p, i) => [p.id, i]) ); @@ -118,6 +119,8 @@ export default function ModelPage() { const n = packages.length; const rank = rankById.get(pkg.id) ?? 0; const tierT = n <= 1 ? 0 : rank / (n - 1); + const tierNumber = String(rank + 1).padStart(2, '0'); + const tierLabel = tierLabels[Math.min(Math.floor(tierT * tierLabels.length), tierLabels.length - 1)]; const bgRgb = materialRgbAt(materials, tierT, 'bg').map(Math.round); const accentRgbFloat = materialRgbAt(materials, tierT, 'accent'); @@ -151,6 +154,8 @@ export default function ModelPage() { return { isDarkCard, mutedColor, + tierNumber, + tierLabel, priceColor: `rgb(${priceRgb.join(', ')})`, iconChipStyle: { backgroundColor: `rgba(${accentRgb.join(', ')}, 0.16)`, @@ -198,7 +203,7 @@ export default function ModelPage() {
{packages.map((pkg) => { - const { isDarkCard, style, priceColor, mutedColor, iconChipStyle } = styleOf(pkg); + const { isDarkCard, style, priceColor, mutedColor, iconChipStyle, tierNumber, tierLabel } = styleOf(pkg); return (
@@ -208,6 +213,10 @@ export default function ModelPage() { )} +

+ {tierNumber} · {tierLabel} +

+ {pkg.icon_name && (