);
}
/**
* Main dashboard content with reduced complexity
*/
function DashboardContent() {
const { data: session, status } = useSession();
const router = useRouter();
const [metrics, setMetrics] = useState(null);
// Remove unused company state that was causing skeleton view to always show
const [refreshing, setRefreshing] = useState(false);
const [isInitialLoad, setIsInitialLoad] = useState(true);
const isAuditor = session?.user?.role === "AUDITOR";
const dataHelpers = useDashboardData(metrics);
// Function to fetch metrics with optional date range
// tRPC query for dashboard metrics
const {
data: overviewData,
isLoading: isLoadingMetrics,
refetch: refetchMetrics,
error: metricsError,
} = trpc.dashboard.getOverview.useQuery(
{
// Add date range parameters when implemented
// startDate: dateRange?.startDate,
// endDate: dateRange?.endDate,
},
{
enabled: status === "authenticated",
}
);
// Update state when data changes
useEffect(() => {
if (overviewData) {
// Map overview data to metrics format expected by the component
const mappedMetrics: Partial = {
totalSessions: overviewData.totalSessions,
avgSessionsPerDay: overviewData.avgSessionsPerDay || 0,
avgSessionLength: overviewData.avgSessionLength || 0,
days:
overviewData.timeSeriesData?.reduce(
(acc, item) => {
if (item.date) {
acc[item.date] = item.sessionCount || 0;
}
return acc;
},
{} as Record
) || {},
languages:
overviewData.languageDistribution?.reduce(
(acc, item) => {
if (item.language) {
acc[item.language] = item.count;
}
return acc;
},
{} as Record
) || {},
countries:
overviewData.geographicDistribution?.reduce(
(acc, item) => {
if (item.country) {
acc[item.country] = item.count;
}
return acc;
},
{} as Record
) || {},
belowThresholdCount: overviewData.belowThresholdCount || 0,
// Map sentiment data to individual counts
sentimentPositiveCount:
overviewData.sentimentDistribution?.find(
(s) => s.sentiment === "POSITIVE"
)?.count || 0,
sentimentNeutralCount:
overviewData.sentimentDistribution?.find(
(s) => s.sentiment === "NEUTRAL"
)?.count || 0,
sentimentNegativeCount:
overviewData.sentimentDistribution?.find(
(s) => s.sentiment === "NEGATIVE"
)?.count || 0,
// Map category data to CategoryMetrics format
...(overviewData.categoryDistribution && {
categories: overviewData.categoryDistribution.reduce(
(acc, item) => {
if (item.category) {
acc[item.category] = item.count;
}
return acc;
},
{} as Record
),
}),
};
setMetrics(mappedMetrics as MetricsResult);
if (isInitialLoad) {
setIsInitialLoad(false);
}
}
}, [overviewData, isInitialLoad]);
// Admin refresh sessions mutation
const refreshSessionsMutation = trpc.admin.refreshSessions.useMutation({
onSuccess: () => {
// Refetch metrics after successful refresh
refetchMetrics();
},
onError: (error) => {
alert(`Failed to refresh sessions: ${error.message}`);
},
});
useEffect(() => {
// Redirect if not authenticated
if (status === "unauthenticated") {
router.push("/login");
return;
}
// tRPC queries handle data fetching automatically
}, [status, router]);
// Enhanced error handling with user feedback
if (metricsError) {
return (
Failed to load dashboard data
There was an error loading your dashboard metrics. Please try
refreshing the page.
);
}
async function handleRefresh() {
if (isAuditor) return;
setRefreshing(true);
try {
await refreshSessionsMutation.mutateAsync();
} finally {
setRefreshing(false);
}
}
// Show loading state while session status is being determined
const loadingState = DashboardLoadingStates({ status });
if (loadingState) return loadingState;
// Show loading state while data is being fetched
if (isLoadingMetrics && !metrics) {
return (
Loading dashboard data...
);
}
if (!metrics) {
return ;
}
return (
{/* Date Range Picker */}
{/* {dateRange && (
)} */}
{/* Charts Section */}
{/* Geographic and Topics Section */}
Geographic Distribution
Common Topics
{/* Top Questions Chart */}
{/* Response Time Distribution */}
Response Time Distribution
{/* Token Usage Summary */}
AI Usage & Costs
Total Tokens:
{metrics.totalTokens?.toLocaleString() || 0}
Total Cost:€
{metrics.totalTokensEur?.toFixed(4) || 0}
Token usage chart will be implemented with historical data
);
}
export default function DashboardPage() {
return ;
}