Put in a recent project picker
This commit is contained in:
@@ -4,90 +4,128 @@ import { Chat } from "./components/Chat";
|
||||
import "./App.css";
|
||||
|
||||
function App() {
|
||||
const [projectPath, setProjectPath] = React.useState<string | null>(null);
|
||||
const [errorMsg, setErrorMsg] = React.useState<string | null>(null);
|
||||
const [pathInput, setPathInput] = React.useState("");
|
||||
const [isOpening, setIsOpening] = React.useState(false);
|
||||
const [projectPath, setProjectPath] = React.useState<string | null>(null);
|
||||
const [errorMsg, setErrorMsg] = React.useState<string | null>(null);
|
||||
const [pathInput, setPathInput] = React.useState("");
|
||||
const [isOpening, setIsOpening] = React.useState(false);
|
||||
const [knownProjects, setKnownProjects] = React.useState<string[]>([]);
|
||||
|
||||
async function openProject(path: string) {
|
||||
if (!path.trim()) {
|
||||
setErrorMsg("Please enter a project path.");
|
||||
return;
|
||||
}
|
||||
React.useEffect(() => {
|
||||
api
|
||||
.getKnownProjects()
|
||||
.then((projects) => setKnownProjects(projects))
|
||||
.catch((error) => console.error(error));
|
||||
}, []);
|
||||
|
||||
try {
|
||||
setErrorMsg(null);
|
||||
setIsOpening(true);
|
||||
const confirmedPath = await api.openProject(path.trim());
|
||||
setProjectPath(confirmedPath);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
const message =
|
||||
e instanceof Error
|
||||
? e.message
|
||||
: typeof e === "string"
|
||||
? e
|
||||
: "An error occurred opening the project.";
|
||||
setErrorMsg(message);
|
||||
} finally {
|
||||
setIsOpening(false);
|
||||
}
|
||||
}
|
||||
async function openProject(path: string) {
|
||||
if (!path.trim()) {
|
||||
setErrorMsg("Please enter a project path.");
|
||||
return;
|
||||
}
|
||||
|
||||
function handleOpen() {
|
||||
void openProject(pathInput);
|
||||
}
|
||||
try {
|
||||
setErrorMsg(null);
|
||||
setIsOpening(true);
|
||||
const confirmedPath = await api.openProject(path.trim());
|
||||
setProjectPath(confirmedPath);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
const message =
|
||||
e instanceof Error
|
||||
? e.message
|
||||
: typeof e === "string"
|
||||
? e
|
||||
: "An error occurred opening the project.";
|
||||
setErrorMsg(message);
|
||||
} finally {
|
||||
setIsOpening(false);
|
||||
}
|
||||
}
|
||||
|
||||
async function closeProject() {
|
||||
try {
|
||||
await api.closeProject();
|
||||
setProjectPath(null);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
function handleOpen() {
|
||||
void openProject(pathInput);
|
||||
}
|
||||
|
||||
return (
|
||||
<main
|
||||
className="container"
|
||||
style={{ height: "100vh", padding: 0, maxWidth: "100%" }}
|
||||
>
|
||||
{!projectPath ? (
|
||||
<div
|
||||
className="selection-screen"
|
||||
style={{ padding: "2rem", maxWidth: "800px", margin: "0 auto" }}
|
||||
>
|
||||
<h1>AI Code Assistant</h1>
|
||||
<p>Paste a project path to start the Story-Driven Spec Workflow.</p>
|
||||
<input
|
||||
type="text"
|
||||
value={pathInput}
|
||||
placeholder="/path/to/project"
|
||||
onChange={(event) => setPathInput(event.target.value)}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === "Enter") {
|
||||
handleOpen();
|
||||
}
|
||||
}}
|
||||
style={{ width: "100%", padding: "10px", marginTop: "12px" }}
|
||||
/>
|
||||
<button type="button" onClick={handleOpen} disabled={isOpening}>
|
||||
{isOpening ? "Opening..." : "Open Project"}
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="workspace" style={{ height: "100%" }}>
|
||||
<Chat projectPath={projectPath} onCloseProject={closeProject} />
|
||||
</div>
|
||||
)}
|
||||
async function closeProject() {
|
||||
try {
|
||||
await api.closeProject();
|
||||
setProjectPath(null);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
{errorMsg && (
|
||||
<div className="error-message" style={{ marginTop: "20px" }}>
|
||||
<p style={{ color: "red" }}>Error: {errorMsg}</p>
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
);
|
||||
return (
|
||||
<main
|
||||
className="container"
|
||||
style={{ height: "100vh", padding: 0, maxWidth: "100%" }}
|
||||
>
|
||||
{!projectPath ? (
|
||||
<div
|
||||
className="selection-screen"
|
||||
style={{ padding: "2rem", maxWidth: "800px", margin: "0 auto" }}
|
||||
>
|
||||
<h1>AI Code Assistant</h1>
|
||||
<p>Paste a project path to start the Story-Driven Spec Workflow.</p>
|
||||
{knownProjects.length > 0 && (
|
||||
<div style={{ marginTop: "12px" }}>
|
||||
<div style={{ fontSize: "0.9em", color: "#666" }}>
|
||||
Recent projects
|
||||
</div>
|
||||
<ul style={{ listStyle: "none", padding: 0, margin: "8px 0 0" }}>
|
||||
{knownProjects.map((project) => (
|
||||
<li key={project} style={{ marginBottom: "6px" }}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => void openProject(project)}
|
||||
style={{
|
||||
width: "100%",
|
||||
textAlign: "left",
|
||||
padding: "8px 10px",
|
||||
borderRadius: "6px",
|
||||
border: "1px solid #ddd",
|
||||
background: "#f7f7f7",
|
||||
cursor: "pointer",
|
||||
fontFamily: "monospace",
|
||||
fontSize: "0.9em",
|
||||
}}
|
||||
>
|
||||
{project}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
<input
|
||||
type="text"
|
||||
value={pathInput}
|
||||
placeholder="/path/to/project"
|
||||
onChange={(event) => setPathInput(event.target.value)}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === "Enter") {
|
||||
handleOpen();
|
||||
}
|
||||
}}
|
||||
style={{ width: "100%", padding: "10px", marginTop: "12px" }}
|
||||
/>
|
||||
<button type="button" onClick={handleOpen} disabled={isOpening}>
|
||||
{isOpening ? "Opening..." : "Open Project"}
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="workspace" style={{ height: "100%" }}>
|
||||
<Chat projectPath={projectPath} onCloseProject={closeProject} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{errorMsg && (
|
||||
<div className="error-message" style={{ marginTop: "20px" }}>
|
||||
<p style={{ color: "red" }}>Error: {errorMsg}</p>
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
Reference in New Issue
Block a user