diff --git a/app/dashboard/overview/page.tsx b/app/dashboard/overview/page.tsx
index de14944..3df6a23 100644
--- a/app/dashboard/overview/page.tsx
+++ b/app/dashboard/overview/page.tsx
@@ -4,6 +4,7 @@ import { useEffect, useState, useCallback, useRef } from "react";
import { signOut, useSession } from "next-auth/react";
import { useRouter } from "next/navigation";
import { Company, MetricsResult, WordCloudWord } from "../../../lib/types";
+import { formatEnumValue } from "@/lib/format-enums";
import MetricCard from "../../../components/ui/metric-card";
import ModernLineChart from "../../../components/charts/line-chart";
import ModernBarChart from "../../../components/charts/bar-chart";
@@ -259,10 +260,13 @@ function DashboardContent() {
const getCategoriesData = () => {
if (!metrics?.categories) return [];
- return Object.entries(metrics.categories).map(([name, value]) => ({
- name: name.length > 15 ? name.substring(0, 15) + "..." : name,
- value: value as number,
- }));
+ return Object.entries(metrics.categories).map(([name, value]) => {
+ const formattedName = formatEnumValue(name) || name;
+ return {
+ name: formattedName.length > 15 ? formattedName.substring(0, 15) + "..." : formattedName,
+ value: value as number,
+ };
+ });
};
const getLanguagesData = () => {
diff --git a/app/dashboard/sessions/[id]/page.tsx b/app/dashboard/sessions/[id]/page.tsx
index a24742c..4f93a07 100644
--- a/app/dashboard/sessions/[id]/page.tsx
+++ b/app/dashboard/sessions/[id]/page.tsx
@@ -7,6 +7,7 @@ import SessionDetails from "../../../../components/SessionDetails";
import TranscriptViewer from "../../../../components/TranscriptViewer";
import MessageViewer from "../../../../components/MessageViewer";
import { ChatSession } from "../../../../lib/types";
+import { formatCategory } from "@/lib/format-enums";
import Link from "next/link";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
@@ -181,10 +182,10 @@ export default function SessionViewPage() {
- {session.category && session.category !== 'UNRECOGNIZED_OTHER' && session.category !== 'ACCESS_LOGIN' && (
+ {session.category && (
- {session.category.replace(/_/g, ' ').toLowerCase().replace(/\b\w/g, l => l.toUpperCase())}
+ {formatCategory(session.category)}
)}
{session.language && (
diff --git a/app/dashboard/sessions/page.tsx b/app/dashboard/sessions/page.tsx
index 0f88934..731d4e4 100644
--- a/app/dashboard/sessions/page.tsx
+++ b/app/dashboard/sessions/page.tsx
@@ -8,6 +8,7 @@ import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
+import { formatCategory } from "@/lib/format-enums";
import {
MessageSquare,
Search,
@@ -223,7 +224,7 @@ export default function SessionsPage() {
{filterOptions.categories.map((cat) => (
))}
@@ -377,69 +378,81 @@ export default function SessionsPage() {
)}
- {/* Sessions List */}
- {!loading && !error && sessions.length > 0 && (
-
- {sessions.map((session) => (
-
-
-
-
-
-
- ID
-
-
- {session.sessionId || session.id}
-
-
-
-
-
- {new Date(session.startTime).toLocaleDateString()}
-
-
- {new Date(session.startTime).toLocaleTimeString()}
-
-
-
-
-
-
-
+ {/* Sessions List */}
+ {!loading && !error && sessions.length > 0 && (
+
+ {sessions.map((session) => (
+ -
+
+
+
+
-
- {session.category && session.category !== 'UNRECOGNIZED_OTHER' && session.category !== 'ACCESS_LOGIN' && (
-
-
- {session.category.replace(/_/g, ' ').toLowerCase().replace(/\b\w/g, l => l.toUpperCase())}
-
- )}
- {session.language && (
-
-
- {session.language.toUpperCase()}
-
- )}
-
+
+ {session.category && (
+
+
+ {formatCategory(session.category)}
+
+ )}
+ {session.language && (
+
+
+ {session.language.toUpperCase()}
+
+ )}
+
- {session.summary ? (
-
- {session.summary}
-
- ) : session.initialMsg ? (
-
- {session.initialMsg}
-
- ) : null}
-
-
- ))}
-
- )}
+ {session.summary ? (
+
+ {session.summary}
+
+ ) : session.initialMsg ? (
+
+ {session.initialMsg}
+
+ ) : null}
+
+
+
+
+ ))}
+
+ )}
{/* Pagination */}
{totalPages > 0 && (
diff --git a/app/globals.css b/app/globals.css
index 9b62b83..936cc22 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -105,13 +105,13 @@
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
- --muted-foreground: oklch(0.556 0 0);
+ --muted-foreground: oklch(0.45 0 0);
--accent: oklch(0.97 0 0);
- --accent-foreground: oklch(0.205 0 0);
- --destructive: oklch(0.577 0.245 27.325);
- --border: oklch(0.922 0 0);
- --input: oklch(0.922 0 0);
- --ring: oklch(0.708 0 0);
+ --accent-foreground: oklch(0.15 0 0);
+ --destructive: oklch(0.55 0.245 27.325);
+ --border: oklch(0.85 0 0);
+ --input: oklch(0.85 0 0);
+ --ring: oklch(0.6 0 0);
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
@@ -139,13 +139,13 @@
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
- --muted-foreground: oklch(0.65 0 0);
+ --muted-foreground: oklch(0.75 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
- --destructive: oklch(0.704 0.191 22.216);
- --border: oklch(1 0 0 / 15%);
- --input: oklch(1 0 0 / 20%);
- --ring: oklch(0.556 0 0);
+ --destructive: oklch(0.75 0.191 22.216);
+ --border: oklch(1 0 0 / 25%);
+ --input: oklch(1 0 0 / 30%);
+ --ring: oklch(0.75 0 0);
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
diff --git a/components/SessionDetails.tsx b/components/SessionDetails.tsx
index 103add5..e54878a 100644
--- a/components/SessionDetails.tsx
+++ b/components/SessionDetails.tsx
@@ -3,6 +3,7 @@
import { ChatSession } from "../lib/types";
import LanguageDisplay from "./LanguageDisplay";
import CountryDisplay from "./CountryDisplay";
+import { formatCategory } from "@/lib/format-enums";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Separator } from "@/components/ui/separator";
@@ -16,13 +17,7 @@ interface SessionDetailsProps {
* Component to display session details with formatted country and language names
*/
export default function SessionDetails({ session }: SessionDetailsProps) {
- // Helper function to format category names
- const formatCategory = (category: string) => {
- if (category === 'UNRECOGNIZED_OTHER' || category === 'ACCESS_LOGIN') {
- return null; // Don't show these internal enum values
- }
- return category.replace(/_/g, ' ').toLowerCase().replace(/\b\w/g, l => l.toUpperCase());
- };
+ // Using centralized formatCategory utility
return (
@@ -55,7 +50,7 @@ export default function SessionDetails({ session }: SessionDetailsProps) {
)}
- {session.category && formatCategory(session.category) && (
+ {session.category && (
Category
diff --git a/lib/format-enums.ts b/lib/format-enums.ts
new file mode 100644
index 0000000..d901a92
--- /dev/null
+++ b/lib/format-enums.ts
@@ -0,0 +1,69 @@
+/**
+ * Utility functions for formatting database enums into user-friendly text
+ */
+
+// Custom mappings for specific enum values that need special formatting
+const ENUM_MAPPINGS: Record = {
+ // HR/Employment related
+ 'SALARY_COMPENSATION': 'Salary & Compensation',
+ 'CONTRACT_HOURS': 'Contract & Hours',
+ 'SCHEDULE_HOURS': 'Schedule & Hours',
+ 'LEAVE_VACATION': 'Leave & Vacation',
+ 'SICK_LEAVE_RECOVERY': 'Sick Leave & Recovery',
+ 'WORKWEAR_STAFF_PASS': 'Workwear & Staff Pass',
+ 'TEAM_CONTACTS': 'Team & Contacts',
+ 'PERSONAL_QUESTIONS': 'Personal Questions',
+ 'PERSONALQUESTIONS': 'Personal Questions',
+
+ // Process related
+ 'ONBOARDING': 'Onboarding',
+ 'OFFBOARDING': 'Offboarding',
+
+ // Access related
+ 'ACCESS_LOGIN': 'Access & Login',
+
+ // Technical/Other
+ 'UNRECOGNIZED_OTHER': 'General Inquiry',
+
+ // Add more mappings as needed
+};
+
+/**
+ * Formats a database enum value into user-friendly text
+ * @param enumValue - The raw enum value from the database
+ * @returns Formatted string or null if input is empty
+ */
+export function formatEnumValue(enumValue: string | null | undefined): string | null {
+ if (!enumValue) return null;
+
+ // Check for custom mapping first
+ if (ENUM_MAPPINGS[enumValue]) {
+ return ENUM_MAPPINGS[enumValue];
+ }
+
+ // Fallback: convert snake_case to Title Case
+ return enumValue
+ .replace(/_/g, ' ')
+ .toLowerCase()
+ .replace(/\b\w/g, l => l.toUpperCase());
+}
+
+/**
+ * Formats a category enum specifically for display
+ * @param category - The category enum value
+ * @returns Formatted category name or null if empty
+ */
+export function formatCategory(category: string | null | undefined): string | null {
+ return formatEnumValue(category);
+}
+
+/**
+ * Formats an array of enum values into user-friendly text
+ * @param enumValues - Array of enum values
+ * @returns Array of formatted values (filters out null/undefined)
+ */
+export function formatEnumArray(enumValues: (string | null | undefined)[]): string[] {
+ return enumValues
+ .map(value => formatEnumValue(value))
+ .filter((value): value is string => Boolean(value));
+}
\ No newline at end of file