Add initial wrangler configuration for livedash-node project

- Created wrangler.json with project metadata and settings
- Configured D1 database binding for database interaction
- Enabled observability for monitoring
- Added placeholders for smart placement, environment variables, static assets, and service bindings
This commit is contained in:
2025-06-01 04:51:57 +02:00
parent c9e24298cd
commit 0c18e8be57
21 changed files with 14443 additions and 9721 deletions

View File

@ -4,6 +4,10 @@ import { useState, useEffect } from "react";
import { useSession } from "next-auth/react";
import { Company } from "../../../lib/types";
interface CompanyConfigResponse {
company: Company;
}
export default function CompanySettingsPage() {
const { data: session, status } = useSession();
// We store the full company object for future use and updates after save operations
@ -22,7 +26,7 @@ export default function CompanySettingsPage() {
setLoading(true);
try {
const res = await fetch("/api/dashboard/config");
const data = await res.json();
const data = (await res.json()) as CompanyConfigResponse;
setCompany(data.company);
setCsvUrl(data.company.csvUrl || "");
setCsvUsername(data.company.csvUsername || "");
@ -58,10 +62,10 @@ export default function CompanySettingsPage() {
if (res.ok) {
setMessage("Settings saved successfully!");
// Update local state if needed
const data = await res.json();
const data = (await res.json()) as CompanyConfigResponse;
setCompany(data.company);
} else {
const error = await res.json();
const error = (await res.json()) as { message?: string; };
setMessage(
`Failed to save settings: ${error.message || "Unknown error"}`
);

View File

@ -17,6 +17,11 @@ import GeographicMap from "../../../components/GeographicMap";
import ResponseTimeDistribution from "../../../components/ResponseTimeDistribution";
import WelcomeBanner from "../../../components/WelcomeBanner";
interface MetricsApiResponse {
metrics: MetricsResult;
company: Company;
}
// Safely wrapped component with useSession
function DashboardContent() {
const { data: session, status } = useSession(); // Add status from useSession
@ -40,7 +45,7 @@ function DashboardContent() {
const fetchData = async () => {
setLoading(true);
const res = await fetch("/api/dashboard/metrics");
const data = await res.json();
const data = (await res.json()) as MetricsApiResponse;
console.log("Metrics from API:", {
avgSessionLength: data.metrics.avgSessionLength,
avgSessionTimeTrend: data.metrics.avgSessionTimeTrend,
@ -76,10 +81,10 @@ function DashboardContent() {
if (res.ok) {
// Refetch metrics
const metricsRes = await fetch("/api/dashboard/metrics");
const data = await metricsRes.json();
const data = (await metricsRes.json()) as MetricsApiResponse;
setMetrics(data.metrics);
} else {
const errorData = await res.json();
const errorData = (await res.json()) as { error: string; };
alert(`Failed to refresh sessions: ${errorData.error}`);
}
} finally {

View File

@ -8,6 +8,10 @@ import TranscriptViewer from "../../../../components/TranscriptViewer";
import { ChatSession } from "../../../../lib/types";
import Link from "next/link";
interface SessionApiResponse {
session: ChatSession;
}
export default function SessionViewPage() {
const params = useParams();
const router = useRouter(); // Initialize useRouter
@ -30,13 +34,13 @@ export default function SessionViewPage() {
try {
const response = await fetch(`/api/dashboard/session/${id}`);
if (!response.ok) {
const errorData = await response.json();
const errorData = (await response.json()) as { error: string; };
throw new Error(
errorData.error ||
`Failed to fetch session: ${response.statusText}`
);
}
const data = await response.json();
const data = (await response.json()) as SessionApiResponse;
setSession(data.session);
} catch (err) {
setError(
@ -150,16 +154,17 @@ export default function SessionViewPage() {
<p className="text-gray-600">
No transcript content available for this session.
</p>
{session.fullTranscriptUrl && (
<a
href={session.fullTranscriptUrl}
target="_blank"
rel="noopener noreferrer"
className="text-sky-600 hover:underline mt-2 inline-block"
>
View Source Transcript URL
</a>
)}
{session.fullTranscriptUrl &&
process.env.NODE_ENV !== "production" && (
<a
href={session.fullTranscriptUrl}
target="_blank"
rel="noopener noreferrer"
className="text-sky-600 hover:underline mt-2 inline-block"
>
View Source Transcript URL
</a>
)}
</div>
)}
</div>

View File

@ -14,6 +14,11 @@ interface FilterOptions {
languages: string[];
}
interface SessionsApiResponse {
sessions: ChatSession[];
totalSessions: number;
}
export default function SessionsPage() {
const [sessions, setSessions] = useState<ChatSession[]>([]);
const [loading, setLoading] = useState(true);
@ -58,7 +63,7 @@ export default function SessionsPage() {
if (!response.ok) {
throw new Error("Failed to fetch filter options");
}
const data = await response.json();
const data = (await response.json()) as FilterOptions;
setFilterOptions(data);
} catch (err) {
setError(
@ -88,7 +93,7 @@ export default function SessionsPage() {
if (!response.ok) {
throw new Error(`Failed to fetch sessions: ${response.statusText}`);
}
const data = await response.json();
const data = (await response.json()) as SessionsApiResponse;
setSessions(data.sessions || []);
setTotalPages(Math.ceil((data.totalSessions || 0) / pageSize));
} catch (err) {

View File

@ -12,6 +12,10 @@ interface UserManagementProps {
session: UserSession;
}
interface UsersApiResponse {
users: UserItem[];
}
export default function UserManagement({ session }: UserManagementProps) {
const [users, setUsers] = useState<UserItem[]>([]);
const [email, setEmail] = useState<string>("");
@ -21,7 +25,7 @@ export default function UserManagement({ session }: UserManagementProps) {
useEffect(() => {
fetch("/api/dashboard/users")
.then((r) => r.json())
.then((data) => setUsers(data.users));
.then((data) => setUsers((data as UsersApiResponse).users));
}, []);
async function inviteUser() {

View File

@ -9,6 +9,10 @@ interface UserItem {
role: string;
}
interface UsersApiResponse {
users: UserItem[];
}
export default function UserManagementPage() {
const { data: session, status } = useSession();
const [users, setUsers] = useState<UserItem[]>([]);
@ -27,7 +31,7 @@ export default function UserManagementPage() {
setLoading(true);
try {
const res = await fetch("/api/dashboard/users");
const data = await res.json();
const data = (await res.json()) as UsersApiResponse;
setUsers(data.users);
} catch (error) {
console.error("Failed to fetch users:", error);
@ -52,7 +56,7 @@ export default function UserManagementPage() {
// Refresh the user list
fetchUsers();
} else {
const error = await res.json();
const error = (await res.json()) as { message?: string; };
setMessage(
`Failed to invite user: ${error.message || "Unknown error"}`
);