All files / src/components/Projects ProjectSummary.js

100% Statements 7/7
92.3% Branches 12/13
100% Functions 1/1
100% Lines 7/7

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                            1x 7x 7x   7x   7x 1x     6x                          
import React from 'react';
import { getAboutSection } from './projectsUtils';
 
/**
 * Renders the descriptive summary for a single project card.
 * Selects the best available text in priority order: German translation >
 * README About section > default summary. Falls back to a skeleton placeholder
 * while content is unavailable.
 *
 * @param {object} project - Project data object
 * @param {string} language - Active i18n locale code (e.g. 'en', 'de')
 * @param {Function} t - i18next translation function
 * @returns {JSX.Element}
 */
const ProjectSummary = ({ project, language, t }) => {
  const about = getAboutSection(project.object?.text);
  const isGerman = language === 'de';
  // Priority: explicit German summary > README About text > generic summary
  const displaySummary = (isGerman && project.summary_de) ? project.summary_de : (about || project.summary);
 
  if (!displaySummary?.trim()) {
    return <div data-testid="project-summary-skeleton" className="skeleton-description short skeleton" style={{ width: '60%' }} />;
  }
 
  return (
    <p>
      {displaySummary}
      {isGerman && !project.summary_de && (
        <span style={{ fontStyle: 'italic', marginLeft: '8px', color: '#666', fontSize: '0.9em' }}>
          ({t('translationMissing') || 'Übersetzung fehlt'})
        </span>
      )}
    </p>
  );
};
 
export default ProjectSummary;