/** * Experimental conditions panel for a selected chain * Displays method, resolution, pH, temperature, details, and RCSB link */ import React, { useState } from 'react'; import { ChainMetadata } from '../../../types/protein'; import { formatText, formatPH, formatTemperature, truncateText } from '../../../utils/format'; interface ExperimentalConditionsPanelProps { metadata: ChainMetadata | null; isLoading?: boolean; } const ExperimentalConditionsPanel: React.FC = ({ metadata, isLoading }) => { const [showFullDetails, setShowFullDetails] = useState(false); if (isLoading) { return (

Experimental Conditions

Loading conditions...
); } if (!metadata) { return (

Experimental Conditions

No experimental data available
); } // Safe extraction with optional chaining and nullish coalescing const pdbId = metadata.pdb_id || metadata.entry?.rcsb_id; const website = pdbId ? `https://www.rcsb.org/structure/${String(pdbId).toUpperCase()}` : null; const exptlMethod = metadata.entry?.exptl_method; const pH = metadata.entry?.crystal_grow?.pH; const temp = metadata.entry?.crystal_grow?.temp; const details = metadata.entry?.crystal_grow?.pdbx_details; // Safe formatting const formattedMethod = formatText(exptlMethod); const formattedPH = formatPH(pH); const formattedTemp = formatTemperature(temp); const formattedDetails = formatText(details, ''); const detailsPreview = formattedDetails ? truncateText(formattedDetails, 120) : ''; const hasLongDetails = formattedDetails && formattedDetails.length > 120; return (
{/* Title + Method Chip */}

Experimental Conditions

{formattedMethod !== '—' && ( {formattedMethod} )}
{/* Definition List */}
{website && (
Website
RCSB PDB
)}
Method
{formattedMethod}
pH
{formattedPH}
Temperature
{formattedTemp}
{formattedDetails && (
Details
{showFullDetails ? formattedDetails : detailsPreview}
{hasLongDetails && ( )}
)}
); }; export default ExperimentalConditionsPanel;