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 | 1x 18x 1x 22x 22x 22x 22x 2x 2x 2x 20x 20x 3x 3x 20x 3x 3x 20x 2x 2x 20x 2x 4x 4x 20x 20x 6x 14x | import React from 'react';
import { useTranslation } from 'react-i18next';
import { convertRawToBlob } from '../Projects/projectsUtils';
const DocLink = ({ href, label }) => (
<a href={href} target="_blank" rel="noopener noreferrer" className="project-link">
{label}
</a>
);
/**
* Renders documentation links for a single project in the RepoDocs section.
* Checks fields in priority order: placeholder → API docs → architecture overview →
* production URL → test coverage → generic docsLink fallback.
*
* @param {object} project - Enriched project object from useRepoDocs
* @returns {JSX.Element}
*/
const RepoDocLinks = ({ project: p }) => {
const { t, i18n } = useTranslation();
const lang = i18n.language;
const linkLabel = t('viewDocs');
if (p.repoDocs?.placeholder) {
const title = (lang === 'de' && p.repoDocs.placeholder.title_de)
? p.repoDocs.placeholder.title_de
: p.repoDocs.placeholder.title;
const desc = (lang === 'de' && p.repoDocs.placeholder.description_de)
? p.repoDocs.placeholder.description_de
: p.repoDocs.placeholder.description;
return <p style={{ fontStyle: 'italic', color: '#888' }}><strong>{title}</strong> — {desc}</p>;
}
const nodes = [];
if (p.repoDocs?.apiDocumentation?.link) {
const title = (lang === 'de' && p.repoDocs.apiDocumentation.title_de)
? p.repoDocs.apiDocumentation.title_de
: p.repoDocs.apiDocumentation.title;
nodes.push(
<p key="api"><strong>{title}</strong>: <DocLink href={convertRawToBlob(p.repoDocs.apiDocumentation.link)} label={linkLabel} /></p>
);
}
if (p.repoDocs?.architectureOverview?.link) {
const title = (lang === 'de' && p.repoDocs.architectureOverview.title_de)
? p.repoDocs.architectureOverview.title_de
: p.repoDocs.architectureOverview.title;
nodes.push(
<p key="arch"><strong>{title}</strong>: <DocLink href={convertRawToBlob(p.repoDocs.architectureOverview.link)} label={linkLabel} /></p>
);
}
if (p.repoDocs?.productionUrl?.link) {
const title = (lang === 'de' && p.repoDocs.productionUrl.title_de)
? p.repoDocs.productionUrl.title_de
: p.repoDocs.productionUrl.title;
nodes.push(
<p key="url"><strong>{title}</strong>: <DocLink href={convertRawToBlob(p.repoDocs.productionUrl.link)} label={t('urlLabel')} /></p>
);
}
if (Array.isArray(p.repoDocs?.testing?.coverage)) {
p.repoDocs.testing.coverage.forEach((cov, idx) => {
const title = (lang === 'de' && cov.title_de) ? cov.title_de : cov.title;
nodes.push(
<p key={`cov-${idx}`}><strong>{title}</strong>: <DocLink href={convertRawToBlob(cov.link)} label={linkLabel} /></p>
);
});
}
// Only fall back to the generic docsLink when no structured doc fields exist
const hasStructuredLinks = !!(p.repoDocs?.apiDocumentation || p.repoDocs?.architectureOverview || p.docs?.documentation);
if (!hasStructuredLinks && p.docsLink) {
return <p><DocLink href={convertRawToBlob(p.docsLink)} label={t('viewDocs')} /></p>;
}
return <>{nodes}</>;
};
export default RepoDocLinks;
|