Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
713e9ad
feat(*): google integration flow
Ayush8923 Mar 31, 2026
06acfdc
feat(*): added the logout api endpoint
Ayush8923 Mar 31, 2026
b2ef783
fix(*): align the bottom action items tab
Ayush8923 Mar 31, 2026
3fbc5d3
fix(*): UI updates and users flow
Ayush8923 Apr 1, 2026
a236f2d
fix(*): small updates
Ayush8923 Apr 1, 2026
7e45d41
fix(*): some cases handling & UI updates
Ayush8923 Apr 2, 2026
e57c2e4
fix(*): some edge cases handled
Ayush8923 Apr 2, 2026
0e4d1dc
fix(*): authentication handle in the knowledge base
Ayush8923 Apr 2, 2026
bd1e94f
Merge branch 'feat/admin-flow' of https://github.com/ProjectTech4DevA…
Ayush8923 Apr 2, 2026
1b6598b
Merge branch 'feat/admin-flow' of https://github.com/ProjectTech4DevA…
Ayush8923 Apr 2, 2026
525f850
fix(*): remove the js comment
Ayush8923 Apr 2, 2026
8a98eeb
Merge branch 'feat/admin-flow' of https://github.com/ProjectTech4DevA…
Ayush8923 Apr 3, 2026
32826e2
fix(*): some apikey intilization
Ayush8923 Apr 3, 2026
b6d59f8
fix(*): some of the UI updates
Ayush8923 Apr 3, 2026
3301f9d
fix(*): update the api response data
Ayush8923 Apr 4, 2026
9e14e58
fix(*): cleanups & handling refresh token
Ayush8923 Apr 5, 2026
be27625
fix(*): update the default setting route
Ayush8923 Apr 5, 2026
9959073
Merge branch 'feat/admin-flow' into feat/google-integration
Ayush8923 Apr 6, 2026
4a0e744
Merge branch 'feat/admin-flow' into feat/google-integration
Ayush8923 Apr 7, 2026
275fcfc
fix(*): centralize the local storage key and clear the local storage …
Ayush8923 Apr 7, 2026
adb54ec
Merge branch 'feat/admin-flow' of https://github.com/ProjectTech4DevA…
Ayush8923 Apr 8, 2026
05bd0d3
fix(*): UI updates
Ayush8923 Apr 8, 2026
e0c4783
Merge branch 'feat/admin-flow' into feat/google-integration
Ayush8923 Apr 8, 2026
06b672b
cleanups(*): stt and tts flow
Ayush8923 Apr 8, 2026
f985a1e
fix(*): few edge cases handles
Ayush8923 Apr 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
BACKEND_URL=http://localhost:8000
BACKEND_URL=http://localhost:8000
NEXT_PUBLIC_GOOGLE_CLIENT_ID=your-google-client-id.apps.googleusercontent.com
28 changes: 9 additions & 19 deletions app/(main)/configurations/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ export default function ConfigLibraryPage() {
Record<string, number>
>({});
const { sidebarCollapsed } = useApp();
const { activeKey } = useAuth();
const apiKey = activeKey?.key;
const { activeKey, isAuthenticated } = useAuth();
const apiKey = activeKey?.key ?? "";
const [searchInput, setSearchInput] = useState("");
const [debouncedQuery, setDebouncedQuery] = useState("");
const [columnCount, setColumnCount] = useState(3);
Expand Down Expand Up @@ -100,11 +100,11 @@ export default function ConfigLibraryPage() {

useEffect(() => {
const fetchEvaluationCounts = async () => {
if (!activeKey) return;
if (!isAuthenticated) return;
try {
const data = await apiFetch<EvalJob[] | { data: EvalJob[] }>(
"/api/evaluations",
activeKey.key,
apiKey,
);
const jobs: EvalJob[] = Array.isArray(data) ? data : data.data || [];
const counts: Record<string, number> = {};
Expand All @@ -129,7 +129,7 @@ export default function ConfigLibraryPage() {
await existing;
return;
}
if (!apiKey) return;
if (!isAuthenticated) return;

const loadPromise = (async () => {
const res = await apiFetch<{
Expand All @@ -144,15 +144,15 @@ export default function ConfigLibraryPage() {
pendingVersionLoads.set(configId, loadPromise);
await loadPromise;
},
[apiKey],
[apiKey, isAuthenticated],
);

const loadSingleVersion = useCallback(
async (configId: string, version: number): Promise<SavedConfig | null> => {
const key = `${configId}:${version}`;
const existing = pendingSingleVersionLoads.get(key);
if (existing) return existing;
if (!apiKey) return null;
if (!isAuthenticated) return null;

const configPublic =
configs.find((c) => c.id === configId) ??
Expand All @@ -179,7 +179,7 @@ export default function ConfigLibraryPage() {
pendingSingleVersionLoads.set(key, loadPromise);
return loadPromise;
},
[apiKey, configs],
[apiKey, configs, isAuthenticated],
);

const handleCreateNew = () => {
Expand Down Expand Up @@ -277,17 +277,7 @@ export default function ConfigLibraryPage() {
) : error ? (
<div className="rounded-lg p-6 text-center bg-[#fef2f2] border border-[#fecaca]">
<WarningTriangleIcon className="w-12 h-12 mx-auto mb-3 text-[#dc2626]" />
<p className="text-sm font-medium text-[#dc2626]">{error}</p>
<button
onClick={() => router.push("/keystore")}
className="mt-4 px-4 py-2 rounded-md text-sm font-medium transition-colors"
style={{
backgroundColor: colors.accent.primary,
color: colors.bg.primary,
}}
>
Go to Keystore
</button>
<p className="text-sm font-medium text-status-error">{error}</p>
</div>
) : configs.length === 0 ? (
<div
Expand Down
8 changes: 4 additions & 4 deletions app/(main)/configurations/prompt-editor/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function PromptEditorContent() {
const toast = useToast();
const searchParams = useSearchParams();
const { sidebarCollapsed } = useApp();
const { activeKey } = useAuth();
const { activeKey, isAuthenticated } = useAuth();
const urlConfigId = searchParams.get("config");
const urlVersion = searchParams.get("version");
const showHistory = searchParams.get("history") === "true";
Expand Down Expand Up @@ -265,9 +265,9 @@ function PromptEditorContent() {
return;
}

const apiKey = activeKey?.key;
if (!apiKey) {
toast.error("No API key found. Please add an API key in the Keystore.");
const apiKey = activeKey?.key ?? "";
if (!isAuthenticated) {
toast.error("Please log in to save configurations.");
return;
}

Expand Down
133 changes: 24 additions & 109 deletions app/(main)/datasets/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useState, useEffect } from "react";

import { useAuth } from "@/app/lib/context/AuthContext";
import { useApp } from "@/app/lib/context/AppContext";
import { apiFetch } from "@/app/lib/apiClient";
import { APIKey } from "@/app/lib/types/credentials";
import Sidebar from "@/app/components/Sidebar";
import PageHeader from "@/app/components/PageHeader";
Expand Down Expand Up @@ -40,7 +41,7 @@ export default function Datasets() {
const [isUploading, setIsUploading] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const { activeKey: apiKey } = useAuth();
const { activeKey: apiKey, isAuthenticated } = useAuth();

// Pagination state
const [currentPage, setCurrentPage] = useState(1);
Expand All @@ -54,32 +55,19 @@ export default function Datasets() {
}, [apiKey]);

const fetchDatasets = async () => {
if (!apiKey) {
setError("No API key found. Please add an API key in the Keystore.");
if (!isAuthenticated) {
setError("Please log in to continue.");
return;
}

setIsLoading(true);
setError(null);

try {
const response = await fetch("/api/evaluations/datasets", {
method: "GET",
headers: {
"X-API-KEY": apiKey.key,
},
});

if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(
errorData.error ||
errorData.message ||
`Failed to fetch datasets: ${response.status}`,
);
}

const data = await response.json();
const data = await apiFetch<Dataset[] | { data: Dataset[] }>(
"/api/evaluations/datasets",
apiKey?.key ?? "",
);
const datasetList = Array.isArray(data) ? data : data.data || [];
setDatasets(datasetList);
} catch (err: unknown) {
Expand Down Expand Up @@ -117,49 +105,29 @@ export default function Datasets() {
return;
}

if (!apiKey) {
toast.error("No API key found. Please add an API key in the Keystore.");
if (!isAuthenticated) {
toast.error("Please log in to continue.");
return;
}

setIsUploading(true);

try {
// Prepare FormData for upload
const formData = new FormData();
formData.append("file", selectedFile);
formData.append("dataset_name", datasetName.trim());

formData.append("duplication_factor", duplicationFactor || "1");

// Upload to backend
const response = await fetch("/api/evaluations/datasets", {
await apiFetch<Dataset>("/api/evaluations/datasets", apiKey?.key ?? "", {
method: "POST",
body: formData,
headers: {
"X-API-KEY": apiKey.key,
},
});

if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(
errorData.error ||
errorData.message ||
`Upload failed with status ${response.status}`,
);
}

await response.json();
// Refresh datasets list
await fetchDatasets();

// Reset form
setSelectedFile(null);
setDatasetName("");
setDuplicationFactor("1");

// Close modal
setIsModalOpen(false);

toast.success("Dataset uploaded successfully!");
Expand All @@ -174,8 +142,8 @@ export default function Datasets() {
};

const handleDeleteDataset = async (datasetId: number) => {
if (!apiKey) {
toast.error("No API key found");
if (!isAuthenticated) {
toast.error("Please log in to continue");
return;
}

Expand All @@ -185,23 +153,14 @@ export default function Datasets() {
}

try {
const response = await fetch(`/api/evaluations/datasets/${datasetId}`, {
method: "DELETE",
headers: {
"X-API-KEY": apiKey.key,
await apiFetch(
`/api/evaluations/datasets/${datasetId}`,
apiKey?.key ?? "",
{
method: "DELETE",
},
});

if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(
errorData.error ||
errorData.message ||
`Delete failed with status ${response.status}`,
);
}
);

// Refresh datasets list
await fetchDatasets();
toast.success("Dataset deleted successfully");
} catch (error) {
Expand All @@ -212,7 +171,6 @@ export default function Datasets() {
}
};

// Pagination calculations
const indexOfLastItem = currentPage * itemsPerPage;
const indexOfFirstItem = indexOfLastItem - itemsPerPage;
const currentDatasets = datasets.slice(indexOfFirstItem, indexOfLastItem);
Expand All @@ -221,26 +179,17 @@ export default function Datasets() {
const paginate = (pageNumber: number) => setCurrentPage(pageNumber);

return (
<div
className="w-full h-screen flex flex-col"
style={{ backgroundColor: "#fafafa" }}
>
<div className="w-full h-screen flex flex-col bg-bg-secondary">
<div className="flex flex-1 overflow-hidden">
{/* Sidebar */}
<Sidebar collapsed={sidebarCollapsed} activeRoute="/datasets" />

{/* Main Content */}
<div className="flex-1 flex flex-col overflow-hidden">
<PageHeader
title="Datasets"
subtitle="Manage your evaluation datasets"
/>

{/* Content Area */}
<div
className="flex-1 overflow-auto p-6"
style={{ backgroundColor: "#fafafa" }}
>
<div className="flex-1 overflow-auto p-6 bg-bg-secondary">
<div className="max-w-6xl mx-auto space-y-6">
<DatasetListing
datasets={currentDatasets}
Expand All @@ -258,7 +207,6 @@ export default function Datasets() {
</div>
</div>

{/* Upload Dataset Modal */}
{isModalOpen && (
<UploadDatasetModal
selectedFile={selectedFile}
Expand Down Expand Up @@ -363,42 +311,9 @@ function DatasetListing({
<p className="text-sm">Loading datasets...</p>
</div>
) : !apiKey ? (
<div
className="text-center py-12"
style={{ color: "hsl(330, 3%, 49%)" }}
>
<svg
className="mx-auto h-12 w-12 mb-4"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"
/>
</svg>
<p
className="font-medium mb-2"
style={{ color: "hsl(330, 3%, 19%)" }}
>
No API key found
</p>
<p className="text-sm mb-4">
Please add an API key in the Keystore to manage datasets
</p>
<a
href="/keystore"
className="inline-block px-6 py-2 rounded-md text-sm font-medium transition-colors"
style={{
backgroundColor: "#171717",
color: "hsl(0, 0%, 100%)",
}}
>
Go to Keystore
</a>
<div className="text-center py-12 text-text-secondary">
<p className="font-medium mb-2 text-text-primary">Login required</p>
<p className="text-sm">Please log in to manage datasets</p>
</div>
) : error ? (
<div
Expand Down
Loading
Loading