fix: resolve Prettier markdown code block parsing errors

- Fix syntax errors in skills markdown files (.github/skills, .opencode/skills)
- Change typescript to tsx for code blocks with JSX
- Replace ellipsis (...) in array examples with valid syntax
- Separate CSS from TypeScript into distinct code blocks
- Convert JavaScript object examples to valid JSON in docs
- Fix enum definitions with proper comma separation
This commit is contained in:
2026-01-20 21:09:29 +01:00
parent 7932fe7386
commit cd05fc8648
177 changed files with 5042 additions and 5541 deletions

View File

@@ -16,8 +16,13 @@ import {
} from "lucide-react";
import dynamic from "next/dynamic";
import { useRouter } from "next/navigation";
import { signOut, useSession } from "next-auth/react";
import { useCallback, useEffect, useId, useMemo, useState } from "react";
import ModernBarChart from "@/components/charts/bar-chart";
import ModernDonutChart from "@/components/charts/donut-chart";
import ModernLineChart from "@/components/charts/line-chart";
import GeographicMap from "@/components/GeographicMap";
import ResponseTimeDistribution from "@/components/ResponseTimeDistribution";
import TopQuestionsChart from "@/components/TopQuestionsChart";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
@@ -27,19 +32,14 @@ import {
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import MetricCard from "@/components/ui/metric-card";
import { Skeleton } from "@/components/ui/skeleton";
import { authClient } from "@/lib/auth/client";
import { formatEnumValue } from "@/lib/format-enums";
import ModernBarChart from "../../../components/charts/bar-chart";
import ModernDonutChart from "../../../components/charts/donut-chart";
import ModernLineChart from "../../../components/charts/line-chart";
import GeographicMap from "../../../components/GeographicMap";
import ResponseTimeDistribution from "../../../components/ResponseTimeDistribution";
import TopQuestionsChart from "../../../components/TopQuestionsChart";
import MetricCard from "../../../components/ui/metric-card";
import type { Company, MetricsResult } from "../../../lib/types";
import type { Company, MetricsResult } from "@/lib/types";
// Dynamic import for heavy D3-based WordCloud component (~50KB)
const WordCloud = dynamic(() => import("../../../components/WordCloud"), {
const WordCloud = dynamic(() => import("@/components/WordCloud"), {
ssr: false,
loading: () => (
<div className="h-[300px] flex items-center justify-center">
@@ -50,7 +50,7 @@ const WordCloud = dynamic(() => import("../../../components/WordCloud"), {
// Safely wrapped component with useSession
function DashboardContent() {
const { data: session, status } = useSession();
const { data, isPending } = authClient.useSession();
const router = useRouter();
const [metrics, setMetrics] = useState<MetricsResult | null>(null);
const [company, setCompany] = useState<Company | null>(null);
@@ -59,7 +59,7 @@ function DashboardContent() {
const [isInitialLoad, setIsInitialLoad] = useState<boolean>(true);
const refreshStatusId = useId();
const isAuditor = session?.user?.role === "AUDITOR";
// Role-based restrictions removed - all authenticated users have same access
// Function to fetch metrics with optional date range
const fetchMetrics = useCallback(
@@ -92,19 +92,18 @@ function DashboardContent() {
useEffect(() => {
// Redirect if not authenticated
if (status === "unauthenticated") {
router.push("/login");
if (!isPending && !data?.session) {
router.push("/auth/sign-in");
return;
}
// Fetch metrics and company on mount if authenticated
if (status === "authenticated" && isInitialLoad) {
if (!isPending && data?.session && isInitialLoad) {
fetchMetrics(undefined, undefined, true);
}
}, [status, router, isInitialLoad, fetchMetrics]);
}, [isPending, data, router, isInitialLoad, fetchMetrics]);
const handleRefresh = useCallback(async () => {
if (isAuditor) return;
if (!company?.id) {
alert("Cannot refresh: Company ID is missing");
return;
@@ -132,7 +131,7 @@ function DashboardContent() {
} finally {
setRefreshing(false);
}
}, [isAuditor, company?.id]);
}, [company?.id]);
// Memoized data preparation - must be before any early returns (Rules of Hooks)
const sentimentData = useMemo(() => {
@@ -222,7 +221,7 @@ function DashboardContent() {
}, [metrics?.avgResponseTime]);
// Show loading state while session status is being determined
if (status === "loading") {
if (isPending) {
return (
<div className="flex items-center justify-center min-h-[60vh]">
<div className="text-center space-y-4">
@@ -233,7 +232,7 @@ function DashboardContent() {
);
}
if (status === "unauthenticated") {
if (!isPending && !data?.session) {
return (
<div className="flex items-center justify-center min-h-[60vh]">
<div className="text-center">
@@ -335,7 +334,7 @@ function DashboardContent() {
<div className="flex items-center gap-2">
<Button
onClick={handleRefresh}
disabled={refreshing || isAuditor}
disabled={refreshing}
size="sm"
className="gap-2"
aria-label={
@@ -369,7 +368,15 @@ function DashboardContent() {
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem
onClick={() => signOut({ callbackUrl: "/login" })}
onClick={async () => {
await authClient.signOut({
fetchOptions: {
onSuccess: () => {
window.location.href = "/auth/sign-in";
},
},
});
}}
>
<LogOut className="h-4 w-4 mr-2" aria-hidden="true" />
Sign out