diff --git a/src/app/components/nav/Header.tsx b/src/app/components/nav/Header.tsx index 9b85cef..621b0d1 100644 --- a/src/app/components/nav/Header.tsx +++ b/src/app/components/nav/Header.tsx @@ -28,7 +28,6 @@ import { import { ChevronDownIcon } from '@heroicons/react/20/solid' import useAuthStore from '../../store/authStore'; import { Avatar } from '../avatar'; -import LanguageSwitcher from '../LanguageSwitcher'; // Replace current shopItems definition with detailed version (adds icon & description) const shopItems = [ @@ -297,22 +296,31 @@ export default function Header() { Affiliate-Links - {/* Memberships */} - - + {/* Remove Memberships */} {/* Referral Management - match others (no highlight) */} {userPresent && hasReferralPerm && ( - + <> + + {/* New: Personal Matrix */} + + {/* New: Coffee Abonnements */} + + )} {/* About us */} @@ -390,8 +398,20 @@ export default function Header() { - {/* Language & theme remain after auth slot */} - + {/* Replace LanguageSwitcher with English-only dropdown + note */} + + + English + + + We are currently working on implementing other languages. + + + -
- -
+ {/* Replace LanguageSwitcher with English-only dropdown + note for mobile */} + + + Language: English + + + We are currently working on implementing other languages. + + {/* Navigation / Shop after that */}
@@ -623,21 +650,29 @@ export default function Header() { > Affiliate-Links - {/* Memberships */} - - {/* Referral Management - match others (no highlight) */} + {/* Remove Memberships */} + {/* Referral Management + new items */} {hasReferralPerm && ( - + <> + + + + )} {/* About us */} - + {/* Remove Memberships */} + {/* Language (English-only) in logged-out mobile */} +
+ + + Language: English + + + We are currently working on implementing other languages. + + +
-

My Matrix Overview

-

Personal subtree, privacy-preserving beyond level 1.

+

+ {selectedId == null ? 'My Matrices' : 'My Matrix Overview'} +

+

+ {selectedId == null + ? 'Select which matrix you want to inspect.' + : 'Personal subtree, privacy-preserving beyond level 1.'} +

- {error && ( + {/* Errors */} + {matricesError && ( +
+ {matricesError} +
+ )} + {error && selectedId != null && (
{error}
)} -
-
-
Total users under me
-
{data?.totalUsersUnderMe ?? (loading ? '…' : 0)}
-
-
-
Immediate children
-
{data?.immediateChildrenCount ?? (loading ? '…' : 0)}
-
-
-
Levels filled
-
{data?.levelsFilled ?? (loading ? '…' : 0)}
-
-
- -
-
-

Level 1 (Direct Children)

-

- Up to the first five direct children. {data?.rootSlotsRemaining != null ? `Root slots remaining: ${data.rootSlotsRemaining}` : ''} -

-
-
- {loading &&
Loading…
} - {!loading && (data?.level1?.length ?? 0) === 0 && ( -
No direct children.
+ {/* Matrix card list (overview) */} + {selectedId == null && ( +
+ {loadingMatrices && ( +
+
+
+
+
)} -
    - {data?.level1.map((c) => ( -
  • -
    -
    {c.name}
    - - {c.position != null ? `pos ${c.position}` : 'pos —'} - -
    -
    {c.email}
    -
  • - ))} -
-
-
- -
-
-

Level 2+

-

Masked names for deeper descendants.

-
-
- {loading &&
Loading…
} - {!loading && (data?.level2Plus?.length ?? 0) === 0 && ( -
No deeper descendants.
+ {!loadingMatrices && matrices.length === 0 && ( +
+ You are not part of any matrix yet. +
+ )} + {!loadingMatrices && matrices.length > 0 && ( +
    + {matrices.map((m, idx) => { + // Prefer new fields from list; fall back to legacy computed percent + const percent = m.matrixFillPercent ?? m.percentFull ?? 0 + const totalUsersDisplay = m.totalUsersUnderMe ?? m.membersCount ?? m.totalUsers + console.log('[PersonalMatrixPage] Card', idx, { + id: m.id, + name: m.name, + totalUsersUnderMe: m.totalUsersUnderMe, + highestFullLevel: m.highestFullLevel, + matrixFillPercent: m.matrixFillPercent, + legacyPercentFull: m.percentFull, + filledSlots: m.filledSlots, + totalSlots: m.totalSlots, + totalUsers: m.totalUsers, + membersCount: m.membersCount + }) + return ( +
  • +
    +
    {m.name}
    +
    +
    + Total members:{' '} + {totalUsersDisplay != null ? totalUsersDisplay : 'N/A'} +
    +
    + Highest full level:{' '} + {m.highestFullLevel != null ? m.highestFullLevel : 'N/A'} +
    +
    + Matrix fill: +
    +
    +
    + + {Math.max(0, Math.min(100, percent)).toFixed(2)}% + +
    + {m.createdAt && ( +
    + Created:{' '} + {new Date(m.createdAt).toLocaleDateString()} +
    + )} + {m.description && ( +
    + {m.description} +
    + )} +
    +
    + +
    +
    +
  • + ) + })} +
)} -
    - {data?.level2Plus.map((x) => ( -
  • -
    - {x.nameMasked} - L{x.depth} -
    -
  • - ))} -
-
+ )} -
-
Overview meta
-
- Matrix instance: {data?.matrixInstanceId ?? (loading ? '…' : '—')}{' '} - • Level1: {meta.countL1} • Level2+: {meta.countL2Plus} -
-
+ {/* Selected matrix overview */} + {selectedId != null && ( + <> + {/* Stats cards */} +
+
+
Total users under me
+
+ {data?.totalUsersUnderMe ?? (loading ? '…' : 0)} +
+
+
+
Immediate children
+
+ {data?.immediateChildrenCount ?? (loading ? '…' : 0)} +
+
+
+
Levels filled
+
+ {data?.levelsFilled ?? (loading ? '…' : 0)} +
+
+
+ + {/* Level 1 */} +
+
+

Level 1 (Direct Children)

+

+ Up to the first five direct children. {data?.rootSlotsRemaining != null ? `Root slots remaining: ${data.rootSlotsRemaining}` : ''} +

+
+
+ {loading &&
Loading…
} + {!loading && (data?.level1?.length ?? 0) === 0 && ( +
No direct children.
+ )} +
    + {data?.level1.map((c) => ( +
  • +
    +
    {c.name}
    + + {c.position != null ? `pos ${c.position}` : 'pos —'} + +
    +
    {c.email}
    +
  • + ))} +
+
+
+ + {/* Level 2+ */} +
+
+

Level 2+

+

Masked names for deeper descendants.

+
+
+ {loading &&
Loading…
} + {!loading && (data?.level2Plus?.length ?? 0) === 0 && ( +
No deeper descendants.
+ )} +
    + {data?.level2Plus.map((x) => ( +
  • +
    + {x.nameMasked} + L{x.depth} +
    +
  • + ))} +
+
+
+ + {/* Meta */} +
+
Overview meta
+
+ Matrix instance: {data?.matrixInstanceId ?? (loading ? '…' : '—')}{' '} + • Level1: {meta.countL1} • Level2+: {meta.countL2Plus} +
+
+ + )}