summaryrefslogtreecommitdiff
path: root/makima/frontend/src/routes/contracts.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'makima/frontend/src/routes/contracts.tsx')
-rw-r--r--makima/frontend/src/routes/contracts.tsx64
1 files changed, 63 insertions, 1 deletions
diff --git a/makima/frontend/src/routes/contracts.tsx b/makima/frontend/src/routes/contracts.tsx
index f09ec5b..5e9bf60 100644
--- a/makima/frontend/src/routes/contracts.tsx
+++ b/makima/frontend/src/routes/contracts.tsx
@@ -6,7 +6,7 @@ import { ContractDetail } from "../components/contracts/ContractDetail";
import { DirectoryInput } from "../components/mesh/DirectoryInput";
import { useContracts } from "../hooks/useContracts";
import { useAuth } from "../contexts/AuthContext";
-import { createTask, getDaemonDirectories } from "../lib/api";
+import { createTask, getDaemonDirectories, getRepositorySuggestions } from "../lib/api";
import type {
ContractWithRelations,
ContractPhase,
@@ -15,6 +15,7 @@ import type {
CreateContractRequest,
RepositorySourceType,
DaemonDirectory,
+ RepositoryHistoryEntry,
} from "../lib/api";
import { getValidPhases, getDefaultPhase } from "../lib/api";
@@ -81,6 +82,38 @@ function ContractsPageContent() {
const [repoPath, setRepoPath] = useState("");
const [createError, setCreateError] = useState<string | null>(null);
const [suggestedDirectories, setSuggestedDirectories] = useState<DaemonDirectory[]>([]);
+ const [repoSuggestions, setRepoSuggestions] = useState<RepositoryHistoryEntry[]>([]);
+ const [showRepoSuggestions, setShowRepoSuggestions] = useState(false);
+
+ // Fetch repository suggestions when modal opens and repo type changes
+ useEffect(() => {
+ if (isCreating && (repoType === "remote" || repoType === "local")) {
+ getRepositorySuggestions(repoType, undefined, 10)
+ .then((res) => {
+ setRepoSuggestions(res.entries);
+ setShowRepoSuggestions(res.entries.length > 0);
+ })
+ .catch(() => {
+ setRepoSuggestions([]);
+ setShowRepoSuggestions(false);
+ });
+ } else {
+ setRepoSuggestions([]);
+ setShowRepoSuggestions(false);
+ }
+ }, [isCreating, repoType]);
+
+ // Apply a repository suggestion
+ const applyRepoSuggestion = useCallback((suggestion: RepositoryHistoryEntry) => {
+ setRepoName(suggestion.name);
+ if (suggestion.repositoryUrl) {
+ setRepoUrl(suggestion.repositoryUrl);
+ }
+ if (suggestion.localPath) {
+ setRepoPath(suggestion.localPath);
+ }
+ setShowRepoSuggestions(false);
+ }, []);
// Fetch daemon directories when "local" repo type is selected
useEffect(() => {
@@ -540,6 +573,35 @@ function ContractsPageContent() {
</button>
</div>
+ {/* Repository suggestions */}
+ {showRepoSuggestions && repoSuggestions.length > 0 && (
+ <div className="mb-3">
+ <label className="block font-mono text-xs text-[#8b949e] uppercase mb-1">
+ Recent Repositories
+ </label>
+ <div className="border border-[rgba(117,170,252,0.2)] bg-[#0a1525] max-h-32 overflow-y-auto">
+ {repoSuggestions.map((suggestion) => (
+ <button
+ key={suggestion.id}
+ type="button"
+ onClick={() => applyRepoSuggestion(suggestion)}
+ className="w-full text-left px-3 py-2 font-mono text-xs hover:bg-[rgba(117,170,252,0.1)] border-b border-[rgba(117,170,252,0.1)] last:border-b-0"
+ >
+ <div className="flex items-center justify-between">
+ <span className="text-[#9bc3ff] truncate">{suggestion.name}</span>
+ <span className="text-[10px] text-[#556677] ml-2">
+ {suggestion.useCount}×
+ </span>
+ </div>
+ <div className="text-[10px] text-[#556677] truncate">
+ {suggestion.repositoryUrl || suggestion.localPath}
+ </div>
+ </button>
+ ))}
+ </div>
+ </div>
+ )}
+
{/* Repository name */}
<div className="mb-3">
<label className="block font-mono text-xs text-[#8b949e] uppercase mb-1">