StatisticsCanvasView.tsx3.2 KBView on GitHub
/**
 * StatisticsCanvasView
 *
 * Shows a user/team picker in the top bar for all users.
 * Org admins (role 'admin' or 'owner') can switch between members and see Team Overview.
 * Non-admins see the picker disabled (locked to their own name).
 */

import { useState } from 'react';
import type { Canvas } from '@/modules/canvas/types/canvas-types';
import { StatisticsPage } from '@/modules/statistics/components/StatisticsPage';
import { TeamStatisticsView } from '@/modules/statistics/components/TeamStatisticsView';
import { useSession } from '@/modules/auth/utils/auth-client';
import { useTRPC } from '@/providers/query-provider';
import { useQuery } from '@tanstack/react-query';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Users } from 'lucide-react';

interface StatisticsCanvasViewProps {
  canvas: Canvas;
}

const TEAM_VALUE = '__team__';

export function StatisticsCanvasView({ canvas: _canvas }: StatisticsCanvasViewProps) {
  const { data: session } = useSession();
  const currentUserId = session?.user?.id ?? '';

  const trpc = useTRPC();

  // checkAdminAccess hits the DB but is cached for 5 min — gives us the current user's role
  const { data: adminAccess } = useQuery({
    ...trpc.orgAdmin.checkAdminAccess.queryOptions(),
    staleTime: 5 * 60 * 1000,
  });
  const isOrgAdmin = adminAccess?.isAdmin === true;

  // getOrgMembers includes the current user — used to populate the picker
  const { data: membersData } = useQuery({
    ...trpc.crm.getOrgMembers.queryOptions(),
    staleTime: 5 * 60 * 1000,
    enabled: isOrgAdmin,
  });
  const members = membersData?.members ?? [];

  const [selectedValue, setSelectedValue] = useState<string>('me');

  const selectedUserId =
    selectedValue === 'me' || selectedValue === TEAM_VALUE ? undefined : selectedValue;

  const showTeam = selectedValue === TEAM_VALUE;

  const currentUserName =
    members.find((m) => m.id === currentUserId)?.name ??
    session?.user?.name ??
    'Me';

  return (
    <div className="flex h-full w-full flex-col">
      <div className="flex items-center gap-2 border-b border-border/50 px-6 py-2">
        <Select value={selectedValue} onValueChange={setSelectedValue} disabled={!isOrgAdmin}>
          <SelectTrigger size="sm" className="w-52">
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="me" className="text-xs">
              {currentUserName} (me)
            </SelectItem>
            {members
              .filter((m) => m.id !== currentUserId)
              .map((member) => (
                <SelectItem key=[redacted] value={member.id} className="text-xs">
                  {member.name}
                </SelectItem>
              ))}
            <SelectItem value={TEAM_VALUE} className="text-xs">
              <span className="flex items-center gap-1.5">
                <Users className="h-3.5 w-3.5" />
                Team Overview
              </span>
            </SelectItem>
          </SelectContent>
        </Select>
      </div>

      <div className="min-h-0 flex-1 overflow-auto px-4">
        {showTeam ? <TeamStatisticsView /> : <StatisticsPage userId={selectedUserId} />}
      </div>
    </div>
  );
}