104 lines
2.4 KiB
TypeScript
104 lines
2.4 KiB
TypeScript
import { useState } from "react";
|
|
|
|
import { commitChanges } from "../../../api/git-repositories";
|
|
import styles from "./CommitPanel.module.css";
|
|
|
|
interface CommitPanelProps {
|
|
projectId: string;
|
|
repoId: string;
|
|
modified: string[];
|
|
added: string[];
|
|
deleted: string[];
|
|
untracked: string[];
|
|
onCommit: () => void;
|
|
}
|
|
|
|
export const CommitPanel = ({
|
|
projectId,
|
|
repoId,
|
|
modified,
|
|
added,
|
|
deleted,
|
|
untracked,
|
|
onCommit,
|
|
}: CommitPanelProps) => {
|
|
const [message, setMessage] = useState("");
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const allFiles = [...modified, ...added, ...deleted, ...untracked];
|
|
const hasChanges = allFiles.length > 0;
|
|
|
|
const handleCommit = async () => {
|
|
if (!message.trim()) {
|
|
setError("Please enter a commit message");
|
|
return;
|
|
}
|
|
setLoading(true);
|
|
setError(null);
|
|
try {
|
|
await commitChanges(projectId, repoId, message);
|
|
setMessage("");
|
|
onCommit();
|
|
} catch {
|
|
setError("Commit failed. Please try again.");
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
if (!hasChanges) return null;
|
|
|
|
return (
|
|
<div className={styles.commitPanel}>
|
|
<h4>Changes</h4>
|
|
|
|
<div className={styles.fileList}>
|
|
{modified.map((file) => (
|
|
<div key={file} className={`${styles.fileItem} modified`}>
|
|
<span className={styles.fileStatus}>M</span>
|
|
<span>{file}</span>
|
|
</div>
|
|
))}
|
|
{added.map((file) => (
|
|
<div key={file} className={`${styles.fileItem} added`}>
|
|
<span className={styles.fileStatus}>A</span>
|
|
<span>{file}</span>
|
|
</div>
|
|
))}
|
|
{deleted.map((file) => (
|
|
<div key={file} className={`${styles.fileItem} deleted`}>
|
|
<span className={styles.fileStatus}>D</span>
|
|
<span>{file}</span>
|
|
</div>
|
|
))}
|
|
{untracked.map((file) => (
|
|
<div key={file} className={`${styles.fileItem} untracked`}>
|
|
<span className={styles.fileStatus}>?</span>
|
|
<span>{file}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<div className={styles.commitForm}>
|
|
<textarea
|
|
placeholder="Commit message"
|
|
value={message}
|
|
onChange={(e) => setMessage(e.target.value)}
|
|
rows={2}
|
|
className={styles.commitMessageInput}
|
|
/>
|
|
{error && <div className={styles.commitError}>{error}</div>}
|
|
<button
|
|
onClick={handleCommit}
|
|
disabled={loading || !message.trim()}
|
|
className={styles.commitButton}
|
|
type="button"
|
|
>
|
|
{loading ? "Committing..." : "Commit"}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|