Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/app/helpers/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,13 @@ export default function HelpersPage() {
if (!helpersData) return []
return helpersData.map((helper) => ({
id: helper.helper_id,
// Must match the helper profile page (/helpers/[id]) so avatar colors are consistent
avatarId: helper.user_id ?? helper.helper_id,
name: helper.user?.name || "Unknown",
initial: (helper.user?.name || "U")[0].toUpperCase(),
discordUser: helper.user?.username || "-",
githubAccount: helper.user?.username || "-",
category: helper.category || "Community",
color: getAvatarColorHexForId(helper.user_id ?? helper.helper_id),
avatarUrl: helper.user?.avatar_url ?? null,
isRegistered: !!helper.user_id,
}))
Expand Down Expand Up @@ -663,7 +664,7 @@ export default function HelpersPage() {
</div>
<div className="col-span-3 flex items-center gap-[18px]">
<ProfileAvatar
id={helper.id}
id={helper.avatarId}
name={helper.name}
avatarUrl={helper.avatarUrl}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/app/reports/support/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export default function ReportsSupportPage() {

let list = transfersData.map((transfer) => {
const helperName = getHelperDisplayName(transfer.helper)
const { initial, color } = getHelperInitialAndColor(helperName, transfer.helper_id)
const { initial, color } = getHelperInitialAndColor(helperName, transfer.helper?.user_id ?? transfer.helper_id)
const dateStr = transfer.completed_at || transfer.created_at
return {
id: transfer.id,
Expand Down
20 changes: 17 additions & 3 deletions src/app/slas/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ interface TicketRow {

interface HelperPublic {
helper_id: string
user_id: string | null
user: { name: string } | null
}

Expand Down Expand Up @@ -100,12 +101,13 @@ export default function SLADetailsPage({ params }: { params: Promise<{ id: strin
queryFn: async () => {
const { data, error } = await supabase
.from("projects_helpers")
.select("helper_id, user:users_public(name)")
.select("helper_id, user_id, user:users_public(name)")
.eq("project_id", sla!.project_id)
if (error) throw error
// Supabase returns user as array when using foreign tables
return ((data ?? []) as any[]).map((h) => ({
helper_id: h.helper_id,
user_id: h.user_id ?? null,
user: Array.isArray(h.user) ? (h.user[0] ?? null) : (h.user ?? null),
})) as HelperPublic[]
},
Expand Down Expand Up @@ -152,6 +154,15 @@ export default function SLADetailsPage({ params }: { params: Promise<{ id: strin
return map
}, [projectHelpers])

// helper_id → avatar key (user_id, falling back to helper_id) so colors match the helpers list/profile
const helperAvatarKeyMap = useMemo(() => {
const map = new Map<string, string>()
projectHelpers.forEach((h) => {
map.set(h.helper_id, h.user_id ?? h.helper_id)
})
return map
}, [projectHelpers])

// ---- Compute stats ------------------------------------------------------
const stats = useMemo(() => {
const solved = filteredTickets.filter((t) => t.status === "completed" || t.status === "cancelled").length
Expand Down Expand Up @@ -497,7 +508,7 @@ export default function SLADetailsPage({ params }: { params: Promise<{ id: strin
<div className="flex items-center gap-3">
<div
className="w-8 h-8 rounded-full flex items-center justify-center text-white text-sm font-semibold"
style={{ backgroundColor: avatarColor(helper.name) }}
style={{ backgroundColor: avatarColor(helperAvatarKeyMap.get(helper.id) ?? helper.id) }}
>
{getInitial(helper.name)}
</div>
Expand Down Expand Up @@ -578,6 +589,9 @@ export default function SLADetailsPage({ params }: { params: Promise<{ id: strin
const claimedParticipant = ticket.tickets_participants.find((p) => p.claimed)
const primaryHelperId = claimedParticipant?.participant_id
const primaryHelperName = primaryHelperId ? (helperMap.get(primaryHelperId) ?? "Unknown") : "—"
const primaryHelperAvatarKey = primaryHelperId
? (helperAvatarKeyMap.get(primaryHelperId) ?? primaryHelperId)
: null

const ticketMs = ticket.tickets_time_entries.reduce(
(sum, e) => sum + (e.time_milliseconds ?? 0), 0
Expand All @@ -600,7 +614,7 @@ export default function SLADetailsPage({ params }: { params: Promise<{ id: strin
<div className="flex items-center gap-2">
<div
className="w-6 h-6 rounded-full flex items-center justify-center text-xs font-semibold"
style={{ backgroundColor: avatarColor(primaryHelperName) }}
style={{ backgroundColor: avatarColor(primaryHelperAvatarKey) }}
>
{getInitial(primaryHelperName)}
</div>
Expand Down
2 changes: 2 additions & 0 deletions src/hooks/usePayments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export interface PaymentTransfer {
created_at: string
completed_at: string | null
helper?: {
user_id?: string | null
user?: {
name: string
username: string | null
Expand Down Expand Up @@ -83,6 +84,7 @@ export function usePaymentTransfers(filters?: {
.select(`
*,
helper:projects_helpers(
user_id,
user:users_public(name, username, email)
),
ticket:tickets(id, title, sla:slas(name))
Expand Down