333 lines
20 KiB
HTML
333 lines
20 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
|
|
<title>Function</title>
|
|
<link rel="icon" type="image/svg+xml"
|
|
href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='1.5' stroke='currentColor' class='w-6 h-6'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='m6.75 7.5 3 2.25-3 2.25m4.5 0h3m-9 8.25h13.5A2.25 2.25 0 0 0 21 18V6a2.25 2.25 0 0 0-2.25-2.25H5.25A2.25 2.25 0 0 0 3 6v12a2.25 2.25 0 0 0 2.25 2.25Z' /%3E%3C/svg%3E%0A" />
|
|
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,900&display=swap" rel="stylesheet" />
|
|
<script src="/static/js/tailwindcss@3.2.4.js"></script>
|
|
<script src="/static/js/htmx.min.js"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.1/ace.min.js"
|
|
integrity="sha512-7QPOFYWq4euLbAVbG/o5YVgkotUdMiwFuFrVQc6lbqZuAcWnLp0sQ6JX2AIWqbm3wWrPuEfu9FqckItCgQzBWw=="
|
|
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.1/mode-javascript.min.js"
|
|
integrity="sha512-1OTGICMOnGWxRYfDZRUdv7qut0O8+9s7JPi6JNxlz1pdpHgDwPo1L0dzYKwftuIb0ossdBzWtkAlnyyYpIEp2A=="
|
|
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.1/theme-monokai.min.js"
|
|
integrity="sha512-g9yptARGYXbHR9r3kTKIAzF+vvmgEieTxuuUUcHC5tKYFpLR3DR+lsisH2KZJG2Nwaou8jjYVRdbbbBQI3Bo5w=="
|
|
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
|
|
|
<script src="https://unpkg.com/mithril/mithril.js"></script>
|
|
<script src="/static/js/mithril/editor.js"></script>
|
|
<script src="/static/js/mithril/responseView.js"></script>
|
|
<script src="/static/js/mithril/alert.js"></script>
|
|
<script src="https://unpkg.com/ace-diff@^2"></script>
|
|
<link href="https://unpkg.com/ace-diff@^2/dist/ace-diff.min.css" rel="stylesheet">
|
|
|
|
<style>
|
|
@import url("https://rsms.me/inter/inter.css");
|
|
|
|
html {
|
|
font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
|
|
Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
|
|
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
|
|
"Noto Color Emoji";
|
|
}
|
|
|
|
.gradient {
|
|
background-image: linear-gradient(-225deg, #cbbacc 0%, #2580b3 100%);
|
|
}
|
|
|
|
button,
|
|
.gradient2 {
|
|
background-color: #f39f86;
|
|
background-image: linear-gradient(315deg, #f39f86 0%, #f9d976 74%);
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body class="gradient leading-relaxed tracking-wide flex flex-col">
|
|
<div class="container mx-auto p-4 lg:p-1 min-h-screen h-full">
|
|
|
|
<nav id="header" class="w-full z-30 top-0 text-white py-1 lg:py-1">
|
|
<div class="w-full container mx-auto flex flex-wrap items-center justify-between mt-0 px-2 py-2 lg:py-6">
|
|
<div class="pl-4 flex items-center">
|
|
<a class="text-white no-underline hover:no-underline font-bold text-2xl lg:text-4xl" href="#">
|
|
<svg class="h-10 w-10 inline-block fill-current text-yellow-700"
|
|
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
|
<path d="M13 8V0L8.11 5.87 3 12h4v8L17 8h-4z"></path>
|
|
</svg></a>
|
|
</div>
|
|
|
|
<div class="block lg:hidden pr-4">
|
|
<button id="nav-toggle"
|
|
class="flex items-center px-3 py-2 border rounded text-gray-500 border-gray-600 hover:text-gray-800 hover:border-green-500 appearance-none focus:outline-none">
|
|
<svg class="fill-current h-3 w-3" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
|
<title>Menu</title>
|
|
<path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"></path>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="w-full flex-grow lg:flex lg:items-center lg:w-auto hidden lg:block mt-2 lg:mt-0 text-black p-4 lg:p-0 z-20"
|
|
id="nav-content">
|
|
<ul class="list-reset lg:flex justify-end flex-1 items-center">
|
|
<li class="mr-3">
|
|
<a class="inline-block py-2 px-4 text-black font-bold no-underline" href="#">Home</a>
|
|
</li>
|
|
<li class="mr-3">
|
|
<a class="inline-block text-black no-underline hover:text-gray-800 hover:text-underline py-2 px-4"
|
|
href="{{ url_for('documentation') }}">Documentation</a>
|
|
</li>
|
|
<li class="mr-3">
|
|
<a class="inline-block text-black no-underline hover:text-gray-800 hover:text-underline py-2 px-4"
|
|
href="#">About</a>
|
|
</li>
|
|
</ul>
|
|
<a href="{{ url_for('home.index') }}"
|
|
class="mx-auto lg:mx-0 hover:underline gradient2 text-gray-800 font-extrabold rounded my-6 py-4 px-8 shadow-lg cursor-pointer">Login</a>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<div class="text-center px-3 lg:px-0">
|
|
<h1 class="my-4 text-2xl md:text-3xl lg:text-5xl font-black leading-tight">Build HTTP and Timer Functions
|
|
with Ease
|
|
|
|
</h1>
|
|
<p class="leading-normal text-gray-800 text-base md:text-xl lg:text-2xl">No DevOps, Git, or command-line -
|
|
just your
|
|
browser.
|
|
</p>
|
|
<p class="leading-normal text-gray-800 text-base md:text-xl lg:text-2xl mb-8">
|
|
Focus on coding; we handle the deployment seamlessly.
|
|
</p>
|
|
|
|
<a class="mx-auto lg:mx-0 hover:underline gradient2 text-gray-800 font-extrabold rounded my-6 py-4 px-8 shadow-lg cursor-pointer"
|
|
href="{{ url_for('auth.signup') }}">
|
|
Sign Up
|
|
</a>
|
|
<a href="{{ url_for('documentation') }}"
|
|
class="inline-block mx-auto lg:mx-0 hover:underline bg-transparent text-gray-600 font-extrabold my-2 md:my-6 py-2 lg:py-4 px-8">
|
|
View documentation</a>
|
|
</div>
|
|
|
|
<div id="app" class="p-1">
|
|
<!-- The Editor component will be mounted here -->
|
|
</div>
|
|
|
|
<script>
|
|
// Mount the component
|
|
m.mount(document.getElementById("app"), {
|
|
view: () => m(Editor, {
|
|
name: '{{ name }}',
|
|
jsValue: {{ script | tojson | safe }},
|
|
jsonValue: {{ environment_info | tojson | safe }},
|
|
isEdit: true,
|
|
showHeader: false,
|
|
showFunctionSettings: false,
|
|
executeUrl: "{{ url_for('execute_code', playground='true') }}",
|
|
generateUrl: "{{ url_for('llm.generate_script') }}"
|
|
})
|
|
})
|
|
</script>
|
|
|
|
{% if public_functions %}
|
|
<section class="py-12">
|
|
<div class="container mx-auto px-4">
|
|
<h2 class="w-full my-2 text-4xl font-black leading-tight text-center text-gray-800">
|
|
Community Highlights
|
|
</h2>
|
|
<div class="w-full mb-8">
|
|
<div class="h-1 mx-auto gradient w-64 opacity-25 my-0 py-0 rounded-t"></div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
|
{% for func in public_functions %}
|
|
<div
|
|
class="bg-white rounded-lg shadow-lg overflow-hidden border border-gray-200 flex flex-col hover:shadow-xl transition-shadow duration-300">
|
|
<div class="p-4 border-b border-gray-200 flex justify-between items-center bg-gray-50">
|
|
<h3 class="font-bold text-lg text-gray-900 truncate" title="{{ func.name }}">
|
|
{{ func.name }}
|
|
</h3>
|
|
<span class="bg-blue-100 text-blue-800 text-xs font-medium px-2.5 py-0.5 rounded uppercase">
|
|
{{ func.runtime }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="relative bg-gray-100 aspect-video border-b border-gray-200 group">
|
|
<iframe
|
|
src="{{ url_for('execute_http_function', user_id=func.user_id, function=func.name + ('/' + func.path if func.path else '')) }}"
|
|
class="w-full h-full border-0" loading="lazy" title="Preview of {{ func.name }}">
|
|
</iframe>
|
|
<a href="{{ url_for('community.view', function_id=func.id) }}"
|
|
class="absolute inset-0 group-hover:bg-opacity-10 transition-all duration-200 flex items-center justify-center">
|
|
<span
|
|
class="opacity-0 group-hover:opacity-100 bg-white text-gray-900 font-bold py-2 px-4 rounded shadow-lg transform scale-95 group-hover:scale-100 transition-all duration-200">
|
|
View Details
|
|
</span>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="p-4 flex-grow flex flex-col justify-between">
|
|
<p class="text-gray-600 text-sm mb-4 line-clamp-3">
|
|
{{ func.description or "No description provided." }}
|
|
</p>
|
|
|
|
<div class="flex items-center justify-between mt-auto pt-4 border-t border-gray-100">
|
|
<div class="flex items-center text-xs text-gray-500">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1" fill="none"
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
|
|
</svg>
|
|
{{ func.username }}
|
|
</div>
|
|
<a href="{{ url_for('community.view', function_id=func.id) }}"
|
|
class="text-blue-600 hover:text-blue-800 text-sm font-medium">
|
|
View & Fork →
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
<div class="text-center mt-10">
|
|
<a href="{{ url_for('community.index') }}"
|
|
class="inline-flex items-center justify-center px-5 py-3 text-base font-medium text-white transition-all bg-blue-600 border border-transparent rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 shadow-md">
|
|
Explore All Functions
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
{% endif %}
|
|
|
|
<section class="py-16">
|
|
<div class="container mx-auto px-4">
|
|
<div class="text-center mb-16">
|
|
<h2 class="text-4xl font-black text-gray-900 mb-4">Everything You Need</h2>
|
|
<p class="text-xl text-gray-600 max-w-2xl mx-auto">
|
|
A complete serverless platform designed for developers who want to ship code, not manage
|
|
infrastructure.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
|
<!-- Feature 1: HTTP Functions -->
|
|
<div
|
|
class="bg-white rounded-xl p-8 shadow-sm hover:shadow-md transition-shadow border border-gray-100">
|
|
<div class="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center mb-6">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-blue-600" fill="none"
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9" />
|
|
</svg>
|
|
</div>
|
|
<h3 class="text-xl font-bold text-gray-900 mb-3">HTTP Endpoints</h3>
|
|
<p class="text-gray-600 leading-relaxed">
|
|
Instantly deploy serverless HTTP functions. Handle GET, POST, and more with full access to
|
|
headers, query params, and body data.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Feature 2: Timer Functions -->
|
|
<div
|
|
class="bg-white rounded-xl p-8 shadow-sm hover:shadow-md transition-shadow border border-gray-100">
|
|
<div class="w-12 h-12 bg-green-100 rounded-lg flex items-center justify-center mb-6">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-green-600" fill="none"
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
</div>
|
|
<h3 class="text-xl font-bold text-gray-900 mb-3">Scheduled Jobs</h3>
|
|
<p class="text-gray-600 leading-relaxed">
|
|
Run code on a schedule without cron servers. Set up recurring tasks or one-time jobs with
|
|
precision timing.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Feature 3: Multi-Runtime -->
|
|
<div
|
|
class="bg-white rounded-xl p-8 shadow-sm hover:shadow-md transition-shadow border border-gray-100">
|
|
<div class="w-12 h-12 bg-purple-100 rounded-lg flex items-center justify-center mb-6">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-purple-600" fill="none"
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" />
|
|
</svg>
|
|
</div>
|
|
<h3 class="text-xl font-bold text-gray-900 mb-3">Polyglot Runtimes</h3>
|
|
<p class="text-gray-600 leading-relaxed">
|
|
Write in your preferred language. First-class support for Node.js, Deno, and Python with
|
|
isolated execution environments.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Feature 4: Persistent Storage -->
|
|
<div
|
|
class="bg-white rounded-xl p-8 shadow-sm hover:shadow-md transition-shadow border border-gray-100">
|
|
<div class="w-12 h-12 bg-yellow-100 rounded-lg flex items-center justify-center mb-6">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-yellow-600" fill="none"
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4" />
|
|
</svg>
|
|
</div>
|
|
<h3 class="text-xl font-bold text-gray-900 mb-3">Built-in State</h3>
|
|
<p class="text-gray-600 leading-relaxed">
|
|
Simple, persistent JSON storage for every function. Keep state between invocations without
|
|
setting up a database.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Feature 5: AI Assistant -->
|
|
<div
|
|
class="bg-white rounded-xl p-8 shadow-sm hover:shadow-md transition-shadow border border-gray-100">
|
|
<div class="w-12 h-12 bg-pink-100 rounded-lg flex items-center justify-center mb-6">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-pink-600" fill="none"
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M13 10V3L4 14h7v7l9-11h-7z" />
|
|
</svg>
|
|
</div>
|
|
<h3 class="text-xl font-bold text-gray-900 mb-3">AI Powered</h3>
|
|
<p class="text-gray-600 leading-relaxed">
|
|
Built-in AI assistant to generate, explain, debug, and optimize your code. Go from idea to
|
|
deployed function in seconds.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Feature 6: Community -->
|
|
<div
|
|
class="bg-white rounded-xl p-8 shadow-sm hover:shadow-md transition-shadow border border-gray-100">
|
|
<div class="w-12 h-12 bg-indigo-100 rounded-lg flex items-center justify-center mb-6">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-indigo-600" fill="none"
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
|
|
</svg>
|
|
</div>
|
|
<h3 class="text-xl font-bold text-gray-900 mb-3">Community Library</h3>
|
|
<p class="text-gray-600 leading-relaxed">
|
|
Discover and fork functions from the community. Share your own creations and collaborate
|
|
with other developers.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
<script>
|
|
document.getElementById('nav-toggle').onclick = function () {
|
|
document.getElementById("nav-content").classList.toggle("hidden");
|
|
}
|
|
</script>
|
|
</body>
|
|
|
|
</html> |