All files / src/components/projects/tabs SeoTab.tsx

88.88% Statements 8/9
100% Branches 10/10
75% Functions 3/4
88.88% Lines 8/9

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                          14x   14x 2x 2x 1x           14x   14x         3x                                                                                
import { useState } from "react";
import { Search } from "lucide-react";
import { SectionCard } from "../../profile/SectionCard";
import { ReadOnlyField } from "../../profile/ReadOnlyField";
import { SeoModal } from "../modals/SeoModal";
import type { Project } from "../../../lib/api";
 
interface SeoTabProps {
	project: Project;
	onSave: (data: Partial<Project>) => void | Promise<void>;
}
 
export function SeoTab({ project, onSave }: SeoTabProps) {
	const [editing, setEditing] = useState(false);
 
	const handleSave = async (data: Partial<Project>) => {
		try {
			await onSave(data);
			setEditing(false);
		} catch {
			// Error is handled by the parent component
		}
	};
 
	const isEmpty = !project.metaTitle && !project.metaDescription && !project.ogImage;
 
	return (
		<div className="space-y-6">
			<SectionCard
				title="SEO Settings"
				icon={<Search className="h-4 w-4" />}
				onEdit={() => setEditing(true)}
				isEmpty={isEmpty}
			>
				<dl className="grid grid-cols-1 gap-4">
					<ReadOnlyField label="SEO Title" value={project.metaTitle} />
					<ReadOnlyField label="SEO Description" value={project.metaDescription} />
					<ReadOnlyField label="Social Share Image" value={project.ogImage} type="url" />
				</dl>
 
				{/* Search Preview */}
				<div className="mt-6 pt-4 border-t border-default">
					<p className="text-sm font-medium text-foreground-default mb-3">
						Search Result Preview
					</p>
					<div className="p-4 bg-background-elevated border border-default rounded-lg">
						<div className="text-sm text-foreground-muted mb-1">
							interioring.com &rsaquo; projects
						</div>
						<div className="text-lg text-info hover:underline cursor-pointer mb-1">
							{project.metaTitle || project.title} - Interior Design Project
						</div>
						<div className="text-sm text-foreground-muted line-clamp-2">
							{project.metaDescription ||
								project.description ||
								"Add a description to help customers find this project."}
						</div>
					</div>
				</div>
			</SectionCard>
 
			{editing && (
				<SeoModal
					project={project}
					onSave={handleSave}
					onClose={() => setEditing(false)}
				/>
			)}
		</div>
	);
}