Files
awesome-reviewers/_layouts/reviewer.html
2025-08-03 22:35:38 +03:00

212 lines
8.4 KiB
HTML

---
layout: default
---
<link rel="stylesheet" href="{{ '/assets/css/reviewer-page.css' | relative_url }}">
<div class="reviewer-detail">
<div class="reviewer-detail-header">
<a href="/" class="back-link">
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
<path fill-rule="evenodd" d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z"/>
</svg>
Back to all reviewers
</a>
<h1 class="reviewer-detail-title">{{ page.title }}</h1>
<div class="reviewer-detail-meta">
<div class="meta-item">
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
<path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 0 1 1-1h8z"/>
</svg>
{{ page.repository }}
</div>
<div class="meta-item">
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
<path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.75.75 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25z"/>
</svg>
Based on {{ page.comments_count | default: "multiple" }} comments
</div>
<div class="meta-item">
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
<path d="M11.013 1.427a1.75 1.75 0 0 1 2.474 0l1.086 1.086a1.75 1.75 0 0 1 0 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 0 1-.927-.928l.929-3.25c.081-.286.235-.547.445-.758l8.61-8.61Zm.176 4.823L9.75 4.81l-6.286 6.287a.253.253 0 0 0-.064.108l-.558 1.953 1.953-.558a.253.253 0 0 0 .108-.064Zm1.238-3.763a.25.25 0 0 0-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 0 0 0-.354Z"/>
</svg>
{{ page.language }}
</div>
</div>
<p class="reviewer-detail-description">{{ page.description }}</p>
<div class="reviewer-detail-tags">
<span class="detail-tag">{{ page.label }}</span>
<span class="detail-tag language">{{ page.language }}</span>
</div>
</div>
<div class="reviewer-content">
<div class="content-header">
<h2 class="content-title">Reviewer Prompt</h2>
<div class="button-group">
<button class="copy-button" onclick="copyPrompt()">
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"/>
<path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"/>
</svg>
<span id="copy-text">Copy Prompt</span>
</button>
<button class="share-button copy-button" onclick="shareFromDrawer(event)">Share</button>
</div>
</div>
<div class="reviewer-prompt" id="prompt-content">{{ content }}</div>
</div>
<div class="stats-grid">
<div class="stat-card">
<div class="stat-value">{{ page.comments_count | default: "N/A" }}</div>
<div class="stat-label">Comments Analyzed</div>
</div>
<div class="stat-card">
<div class="stat-value">{{ page.language }}</div>
<div class="stat-label">Primary Language</div>
</div>
<div class="stat-card">
<div class="stat-value">{{ page.label }}</div>
<div class="stat-label">Category</div>
</div>
</div>
<div class="discussions-section">
<div class="discussion-header">
<h2 class="content-title">Source Discussions</h2>
<span id="discussion-stats" class="discussion-stats"></span>
</div>
<div id="discussion-container"></div>
<div id="discussion-footer" class="discussion-footer"></div>
</div>
</div>
<script>
function htmlToMarkdown(element) {
let markdown = '';
function processNode(node) {
if (node.nodeType === Node.TEXT_NODE) {
return node.textContent;
}
if (node.nodeType === Node.ELEMENT_NODE) {
const tagName = node.tagName.toLowerCase();
const children = Array.from(node.childNodes).map(processNode).join('');
switch (tagName) {
case 'h1': return `# ${children}\n\n`;
case 'h2': return `## ${children}\n\n`;
case 'h3': return `### ${children}\n\n`;
case 'h4': return `#### ${children}\n\n`;
case 'h5': return `##### ${children}\n\n`;
case 'h6': return `###### ${children}\n\n`;
case 'p': return `${children}\n\n`;
case 'strong':
case 'b': return `**${children}**`;
case 'em':
case 'i': return `*${children}*`;
case 'code':
if (node.parentElement && node.parentElement.tagName.toLowerCase() === 'pre') {
return children;
}
return `\`${children}\``;
case 'pre':
const codeElement = node.querySelector('code');
if (codeElement) {
const languageMatch = codeElement.className.match(/(?:language-|hljs-)(\w+)/);
const language = languageMatch ? languageMatch[1] : '';
return `\`\`\`${language}\n${codeElement.textContent}\n\`\`\`\n\n`;
}
return `\`\`\`\n${children}\n\`\`\`\n\n`;
case 'ul':
return `${children}\n`;
case 'ol':
return `${children}\n`;
case 'li':
const parent = node.parentElement;
if (parent.tagName.toLowerCase() === 'ol') {
return `1. ${children}\n`;
} else {
return `- ${children}\n`;
}
case 'blockquote':
return children.split('\n').map(line => `> ${line}`).join('\n') + '\n\n';
case 'br':
return '\n';
default:
return children;
}
}
return '';
}
markdown = processNode(element);
markdown = markdown.replace(/\n{3,}/g, '\n\n').trim();
return markdown;
}
function copyPrompt() {
const promptContent = document.getElementById('prompt-content');
const copyButton = document.querySelector('.copy-button');
const copyText = document.getElementById('copy-text');
const markdownContent = htmlToMarkdown(promptContent);
const textarea = document.createElement('textarea');
textarea.value = markdownContent;
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
copyButton.classList.add('copied');
copyText.textContent = 'Copied!';
setTimeout(() => {
copyButton.classList.remove('copied');
copyText.textContent = 'Copy Prompt';
}, 2000);
}
async function shareFromDrawer(e) {
let slug = location.hash.slice(1);
if (!slug) {
const parts = window.location.pathname.split('/').filter(Boolean);
slug = parts[parts.length - 1];
}
const button = e.currentTarget;
const url = `${window.location.origin}/reviewers/${slug}/`;
try {
if (navigator.clipboard && navigator.clipboard.writeText) {
await navigator.clipboard.writeText(url);
} else {
const textarea = document.createElement('textarea');
textarea.value = url;
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
}
button.classList.add('copied');
button.textContent = 'Copied!';
} catch (err) {
console.error('Copy failed', err);
} finally {
setTimeout(() => {
button.classList.remove('copied');
button.textContent = 'Share';
}, 2000);
}
}
</script>