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

100% Statements 10/10
87.5% Branches 7/8
100% Functions 4/4
100% Lines 10/10

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                                18x 18x   18x   18x 2x 2x 1x           18x           4x                             1x            
import { useState } from "react";
import { Search } from "lucide-react";
import type { Pro } from "../../../lib/api";
import { useUpdateProProfile } from "../../../hooks/mutations/useProMutations";
import { SectionCard } from "../SectionCard";
import { ReadOnlyField } from "../ReadOnlyField";
import { SeoModal } from "../modals/SeoModal";
 
interface SeoTabProps {
	pro: Pro;
	proId: string;
	/** #362: hide Edit affordances for roles the backend will 403 on save. */
	canEdit?: boolean;
}
 
export function SeoTab({ pro, proId, canEdit = true }: SeoTabProps) {
	const updateProfile = useUpdateProProfile(proId);
	const [editingSection, setEditingSection] = useState(false);
 
	const isSeoEmpty = !pro.metaTitle && !pro.metaDescription && !pro.ogImage;
 
	const handleSave = async (data: Partial<Pro>) => {
		try {
			await updateProfile.mutateAsync(data);
			setEditingSection(false);
		} catch {
			// Error toast shown by mutation onError callback
		}
	};
 
	return (
		<div className="space-y-6">
			{/* SEO Settings */}
			<SectionCard
				title="SEO Settings"
				icon={<Search className="h-5 w-5" />}
				onEdit={canEdit ? () => setEditingSection(true) : undefined}
				isEmpty={isSeoEmpty}
			>
				<dl className="grid grid-cols-1 gap-4">
					<ReadOnlyField label="SEO Title" value={pro.metaTitle} />
					<ReadOnlyField label="SEO Description" value={pro.metaDescription} />
					<ReadOnlyField label="Social Share Image" value={pro.ogImage} type="image" />
				</dl>
			</SectionCard>
 
			{/* Modal */}
			{editingSection && (
				<SeoModal
					pro={pro}
					onSave={handleSave}
					onClose={() => setEditingSection(false)}
				/>
			)}
		</div>
	);
}