All files / src/components/blogs RewriteRequestModal.tsx

100% Statements 12/12
85.71% Branches 6/7
100% Functions 4/4
100% Lines 11/11

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127                                        18x 18x   18x 2x 2x 2x       18x   17x           17x                                                                     4x                       51x                                                                                  
import { useState } from "react";
import { X } from "lucide-react";
import { Button } from "../ui/button";
import { useDialogAccessibility } from "../../hooks";
 
interface RewriteRequestModalProps {
	isOpen: boolean;
	onClose: () => void;
	onSubmit: (feedback: string) => void;
	rewritesRemaining: number;
	isSubmitting?: boolean;
}
 
export function RewriteRequestModal({
	isOpen,
	onClose,
	onSubmit,
	rewritesRemaining,
	isSubmitting = false,
}: RewriteRequestModalProps) {
	const [feedback, setFeedback] = useState("");
	const { dialogRef, handleFocusTrap } = useDialogAccessibility(onClose);
 
	const handleSubmit = () => {
		Eif (feedback.trim()) {
			onSubmit(feedback);
			setFeedback("");
		}
	};
 
	if (!isOpen) return null;
 
	const examplePrompts = [
		"Make my quote sound more professional",
		"Add that we specialize in compact spaces",
		"Change the project description to mention the Italian marble we used",
	];
 
	return (
		<div className="fixed inset-0 z-50 flex items-center justify-center bg-overlay-dark" tabIndex={-1}>
			<div
				ref={dialogRef}
				role="dialog"
				aria-modal="true"
				aria-labelledby="rewrite-request-dialog-title"
				onKeyDown={handleFocusTrap}
				className="bg-background-elevated rounded-lg shadow-xl max-w-2xl w-full max-h-[90vh] overflow-y-auto m-4"
			>
				{/* Header */}
				<div className="flex items-center justify-between p-6 border-b border-border-default">
					<h2 id="rewrite-request-dialog-title" className="text-xl font-semibold">Request AI Rewrite</h2>
					<button
						type="button"
						onClick={onClose}
						aria-label="Close"
						className="text-foreground-subtle hover:text-foreground-default"
					>
						<X className="h-5 w-5" />
					</button>
				</div>
 
				{/* Content */}
				<div className="p-6 space-y-6">
					<div>
						<label
							htmlFor="feedback"
							className="block text-sm font-medium mb-2"
						>
							What would you like changed?
						</label>
						<textarea
							id="feedback"
							value={feedback}
							onChange={(e) => setFeedback(e.target.value)}
							placeholder="Example: Make my quote sound more professional. Also mention that we've done 50+ small apartment projects."
							rows={6}
							className="w-full rounded-md border border-border-default bg-background-elevated px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary-500"
						/>
					</div>
 
					{/* Example Prompts */}
					<div>
						<p className="text-sm font-medium mb-2">Example change requests:</p>
						<ul className="space-y-2">
							{examplePrompts.map((prompt) => (
								<li key={prompt} className="text-sm text-foreground-subtle">
									• {prompt}
								</li>
							))}
						</ul>
					</div>
 
					{/* Rewrites Remaining */}
					<div className="p-4 bg-background-muted rounded-lg">
						<p className="text-sm">
							<strong>Rewrites remaining:</strong> {rewritesRemaining} of 3
						</p>
					</div>
 
					{/* Info */}
					<div className="p-4 bg-info-light rounded-lg">
						<p className="text-sm text-info">
							AI will rewrite the relevant sections based on your feedback. You
							can review and approve the new version.
						</p>
					</div>
				</div>
 
				{/* Footer */}
				<div className="flex gap-3 p-6 border-t border-border-default">
					<Button variant="outline" onClick={onClose} className="flex-1">
						Cancel
					</Button>
					<Button
						onClick={handleSubmit}
						disabled={!feedback.trim() || isSubmitting}
						isLoading={isSubmitting}
						className="flex-1"
					>
						Generate New Version
					</Button>
				</div>
			</div>
		</div>
	);
}