Files
function/templates/community/view.html
2025-11-21 10:30:14 +11:00

152 lines
8.6 KiB
HTML

{% extends 'dashboard.html' %}
{% block page %}
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<!-- Back Link -->
<div class="mb-6">
<a href="#" hx-get="{{ url_for('community.index') }}" hx-target="#container" hx-push-url="true"
class="inline-flex items-center text-sm font-medium text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 transition-colors">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="w-4 h-4 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18" />
</svg>
Back to Community Library
</a>
</div>
<!-- Header Section -->
<div class="bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 p-6 mb-6">
<div class="flex flex-col md:flex-row md:items-start md:justify-between gap-4">
<div class="flex-1 min-w-0">
<div class="flex items-center gap-3 mb-2">
<h1 class="text-3xl font-bold text-gray-900 dark:text-white tracking-tight">{{ function.name }}</h1>
<span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300 border border-blue-200 dark:border-blue-800 uppercase tracking-wide">
{{ function.runtime }}
</span>
</div>
<div class="flex flex-wrap items-center gap-4 text-sm text-gray-500 dark:text-gray-400">
<div class="flex items-center gap-1.5">
<div class="p-1 rounded-full bg-gray-100 dark:bg-gray-700">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"
class="w-4 h-4 text-gray-600 dark:text-gray-300">
<path fill-rule="evenodd"
d="M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z"
clip-rule="evenodd" />
</svg>
</div>
<span class="font-medium text-gray-700 dark:text-gray-300">{{ function.username }}</span>
</div>
<span class="hidden sm:inline text-gray-300 dark:text-gray-600"></span>
<div class="flex items-center gap-1.5">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="w-4 h-4">
<path stroke-linecap="round" stroke-linejoin="round"
d="M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 0 1 2.25-2.25h13.5A2.25 2.25 0 0 1 21 7.5v11.25m-18 0h18M5.25 12h13.5h-13.5Zm0 3.75h13.5h-13.5Z" />
</svg>
<span>Published on {{ function.created_at.strftime('%B %d, %Y') }}</span>
</div>
</div>
{% if function.description %}
<div class="mt-4 prose prose-sm dark:prose-invert max-w-none text-gray-600 dark:text-gray-300">
<p class="whitespace-pre-wrap">{{ function.description }}</p>
</div>
{% endif %}
</div>
<div class="flex-shrink-0">
<button hx-post="{{ url_for('community.fork', function_id=function.id) }}" hx-target="#container"
class="inline-flex items-center justify-center px-5 py-2.5 text-sm font-medium text-white transition-all bg-green-600 border border-transparent rounded-lg shadow-sm hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 dark:focus:ring-offset-gray-900">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="w-5 h-5 mr-2 -ml-1">
<path stroke-linecap="round" stroke-linejoin="round"
d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75" />
</svg>
Fork to My Library
</button>
</div>
</div>
</div>
<!-- Tabs & Content -->
<div
class="bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden">
<div class="border-b border-gray-200 dark:border-gray-700">
<nav class="flex -mb-px" aria-label="Tabs">
<button onclick="switchTab('code')" id="tab-code"
class="w-1/2 py-4 px-1 text-center border-b-2 font-medium text-sm focus:outline-none transition-colors border-blue-500 text-blue-600 dark:text-blue-400">
Function Code
</button>
<button onclick="switchTab('env')" id="tab-env"
class="w-1/2 py-4 px-1 text-center border-b-2 font-medium text-sm focus:outline-none transition-colors border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300">
Environment Config
</button>
</nav>
</div>
<div class="p-0">
<div id="content-code" class="block">
<div id="code-editor" class="h-[500px] w-full"></div>
</div>
<div id="content-env" class="hidden">
<div id="env-editor" class="h-[500px] w-full"></div>
</div>
</div>
</div>
</div>
<script>
// Tab Switching Logic
window.switchTab = function (tabName) {
// Update Tab Styles
const tabs = ['code', 'env'];
tabs.forEach(t => {
const btn = document.getElementById(`tab-${t}`);
const content = document.getElementById(`content-${t}`);
if (t === tabName) {
btn.classList.remove('border-transparent', 'text-gray-500', 'hover:text-gray-700', 'hover:border-gray-300', 'dark:text-gray-400', 'dark:hover:text-gray-300');
btn.classList.add('border-blue-500', 'text-blue-600', 'dark:text-blue-400');
content.classList.remove('hidden');
content.classList.add('block');
} else {
btn.classList.add('border-transparent', 'text-gray-500', 'hover:text-gray-700', 'hover:border-gray-300', 'dark:text-gray-400', 'dark:hover:text-gray-300');
btn.classList.remove('border-blue-500', 'text-blue-600', 'dark:text-blue-400');
content.classList.remove('block');
content.classList.add('hidden');
}
});
// Resize editors to ensure they render correctly after visibility change
if (tabName === 'code') codeEditor.resize();
if (tabName === 'env') envEditor.resize();
}
// Initialize Ace Editors
var codeEditor = ace.edit("code-editor");
codeEditor.setTheme("ace/theme/github_dark");
codeEditor.session.setMode("ace/mode/{{ 'python' if function.runtime == 'python' else 'javascript' }}");
codeEditor.setValue({{ function.script_content | tojson | safe }}, -1);
codeEditor.setReadOnly(true);
codeEditor.setOptions({
fontSize: "14px",
showPrintMargin: false,
highlightActiveLine: false,
highlightGutterLine: false
});
var envEditor = ace.edit("env-editor");
envEditor.setTheme("ace/theme/github_dark");
envEditor.session.setMode("ace/mode/json");
envEditor.setValue({{ function.environment_info | safe }}, -1);
envEditor.setReadOnly(true);
envEditor.setOptions({
fontSize: "14px",
showPrintMargin: false,
highlightActiveLine: false,
highlightGutterLine: false
});
</script>
{% endblock %}