Files
headquarter/apps/web/src/components/commit-dialog.tsx
T
Fusion 6f41fa7cbe feat: implement universal icon system with Phosphor Icons
- Install @phosphor-icons/react package
- Create centralized Icon component with size/weight/color variants
- Create icon registry with 34 icons across 5 categories
- Replace all raw Unicode symbols with proper icon components
- Add icons to navigation, buttons, status indicators, git operations
- Add icon CSS with consistent sizing and spacing
- Fix type definitions for Phosphor icon compatibility

Quality gates: typecheck ✓, lint ✓, build ✓ (375KB bundle)
2026-05-19 19:33:06 +02:00

160 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState } from "react";
import { Icon } from "./icon";
interface CommitDialogProps {
isOpen: boolean;
filePath: string;
originalContent: string;
newContent: string;
onCommit: (message: string) => Promise<void>;
onCancel: () => void;
}
export const CommitDialog: React.FC<CommitDialogProps> = ({
isOpen,
filePath,
originalContent,
newContent,
onCommit,
onCancel,
}) => {
const [message, setMessage] = useState("");
const [loading, setLoading] = useState(false);
const [error, setError] = useState(">");
if (!isOpen) return null;
const generateDiff = () => {
const originalLines = originalContent.split("\n");
const newLines = newContent.split("\n");
const maxLines = Math.max(originalLines.length, newLines.length);
const diff: { type: "same" | "added" | "removed"; line: string; lineNum: number }[] = [];
for (let i = 0; i < maxLines; i++) {
const original = originalLines[i] || "";
const updated = newLines[i] || "";
if (original === updated) {
diff.push({ type: "same", line: updated, lineNum: i + 1 });
} else {
if (original) {
diff.push({ type: "removed", line: original, lineNum: i + 1 });
}
if (updated) {
diff.push({ type: "added", line: updated, lineNum: i + 1 });
}
}
}
return diff;
};
const handleCommit = async () => {
if (!message.trim()) {
setError("Please enter a commit message");
return;
}
setLoading(true);
setError("");
try {
await onCommit(message);
} catch {
setError("Failed to commit changes");
} finally {
setLoading(false);
}
};
const diff = generateDiff();
const hasChanges = diff.some((d) => d.type !== "same");
return (
<div className="dialog-overlay">
<div className="commit-dialog">
<div className="dialog-header">
<h3>Commit Changes</h3>
<button className="dialog-close" onClick={onCancel} type="button">
×
</button>
</div>
<div className="dialog-body">
<p className="file-info">
Editing: <strong>{filePath}</strong>
</p>
{!hasChanges && (
<div className="warning-message">No changes to commit</div>
)}
{hasChanges && (
<div className="diff-preview">
<h4>Changes</h4>
<div className="diff-content">
{diff.map((line, i) => (
<div
key={i}
className={`diff-line diff-${line.type}`}
>
<span className="diff-line-number">{line.lineNum}</span>
<span className="diff-marker">
{line.type === "added" && "+"}
{line.type === "removed" && "-"}
{line.type === "same" && " "}
</span>
<span className="diff-line-content">{line.line}</span>
</div>
))}
</div>
</div>
)}
<div className="form-group">
<label>Commit Message *</label>
<textarea
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Describe your changes..."
rows={3}
className="form-textarea"
/>
</div>
{error && <div className="error-message">{error}</div>}
</div>
<div className="dialog-footer">
<button
className="btn-secondary"
onClick={onCancel}
type="button"
>
<Icon name="cancel" size="sm" />
Cancel
</button>
<button
className="btn-primary"
onClick={handleCommit}
disabled={loading || !hasChanges || !message.trim()}
type="button"
>
{loading ? (
<>
<Icon name="loading" size="sm" />
Committing...
</>
) : (
<>
<Icon name="commit" size="sm" />
Commit Changes
</>
)}
</button>
</div>
</div>
</div>
);
};