Squashed 'l2/' content from commit 79caa24
git-subtree-dir: l2 git-subtree-split: 79caa24e2129bf6e2cee819327d5622425306b67
This commit is contained in:
11
app/templates/404.html
Normal file
11
app/templates/404.html
Normal file
@@ -0,0 +1,11 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Not Found - Art-DAG{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="text-center py-16">
|
||||
<h2 class="text-6xl font-bold text-gray-600 mb-4">404</h2>
|
||||
<p class="text-xl text-gray-400 mb-8">Page not found</p>
|
||||
<a href="/" class="text-blue-400 hover:text-blue-300">Go to home page</a>
|
||||
</div>
|
||||
{% endblock %}
|
||||
39
app/templates/activities/list.html
Normal file
39
app/templates/activities/list.html
Normal file
@@ -0,0 +1,39 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Activities - Art-DAG{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h1 class="text-2xl font-bold">Activities</h1>
|
||||
</div>
|
||||
|
||||
{% if activities %}
|
||||
<div class="space-y-4">
|
||||
{% for activity in activities %}
|
||||
<a href="/activities/{{ activity.activity_id }}"
|
||||
class="block bg-gray-800 border border-gray-700 rounded-lg p-4 hover:border-blue-500 transition-colors">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="text-blue-400 font-medium">{{ activity.activity_type }}</span>
|
||||
<span class="text-gray-500 text-sm">{{ activity.published }}</span>
|
||||
</div>
|
||||
<div class="text-gray-300 text-sm truncate">
|
||||
{{ activity.actor_id }}
|
||||
</div>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if has_more %}
|
||||
<div class="mt-6 text-center">
|
||||
<a href="?offset={{ offset + limit }}&limit={{ limit }}"
|
||||
class="text-blue-400 hover:text-blue-300">Load More</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="text-center py-12 text-gray-400">
|
||||
<p>No activities yet.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
47
app/templates/anchors/list.html
Normal file
47
app/templates/anchors/list.html
Normal file
@@ -0,0 +1,47 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Anchors - Art-DAG{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h1 class="text-2xl font-bold">Bitcoin Anchors</h1>
|
||||
</div>
|
||||
|
||||
{% if anchors %}
|
||||
<div class="space-y-4">
|
||||
{% for anchor in anchors %}
|
||||
<div class="bg-gray-800 border border-gray-700 rounded-lg p-4">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="font-mono text-sm text-blue-400 truncate">{{ anchor.merkle_root[:16] }}...</span>
|
||||
{% if anchor.confirmed_at %}
|
||||
<span class="bg-green-600 text-xs px-2 py-1 rounded">Confirmed</span>
|
||||
{% else %}
|
||||
<span class="bg-yellow-600 text-xs px-2 py-1 rounded">Pending</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="text-gray-400 text-sm">
|
||||
{{ anchor.activity_count or 0 }} activities | Created: {{ anchor.created_at }}
|
||||
</div>
|
||||
{% if anchor.bitcoin_txid %}
|
||||
<div class="mt-2 text-xs text-gray-500 font-mono truncate">
|
||||
TX: {{ anchor.bitcoin_txid }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if has_more %}
|
||||
<div class="mt-6 text-center">
|
||||
<a href="?offset={{ offset + limit }}&limit={{ limit }}"
|
||||
class="text-blue-400 hover:text-blue-300">Load More</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="text-center py-12 text-gray-400">
|
||||
<p>No anchors yet.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
58
app/templates/assets/list.html
Normal file
58
app/templates/assets/list.html
Normal file
@@ -0,0 +1,58 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Assets - Art-DAG{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="max-w-6xl mx-auto">
|
||||
<h1 class="text-3xl font-bold mb-6">Your Assets</h1>
|
||||
|
||||
{% if assets %}
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4" id="assets-grid">
|
||||
{% for asset in assets %}
|
||||
<a href="/assets/{{ asset.id }}"
|
||||
class="bg-gray-800 rounded-lg overflow-hidden hover:ring-2 hover:ring-blue-500 transition-all">
|
||||
{% if asset.asset_type == 'image' %}
|
||||
<img src="{{ asset.thumbnail_url or '/assets/' + asset.id + '/thumb' }}"
|
||||
alt="{{ asset.name }}"
|
||||
class="w-full h-40 object-cover">
|
||||
{% elif asset.asset_type == 'video' %}
|
||||
<div class="w-full h-40 bg-gray-900 flex items-center justify-center">
|
||||
<svg class="w-12 h-12 text-gray-600" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path d="M6.3 2.841A1.5 1.5 0 004 4.11V15.89a1.5 1.5 0 002.3 1.269l9.344-5.89a1.5 1.5 0 000-2.538L6.3 2.84z"/>
|
||||
</svg>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="w-full h-40 bg-gray-900 flex items-center justify-center">
|
||||
<span class="text-gray-600">{{ asset.asset_type }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="p-3">
|
||||
<div class="font-medium text-white truncate">{{ asset.name }}</div>
|
||||
<div class="text-xs text-gray-500">{{ asset.asset_type }}</div>
|
||||
{% if asset.ipfs_cid %}
|
||||
<div class="text-xs text-green-400 mt-1">Published</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if has_more %}
|
||||
<div hx-get="/assets?offset={{ offset + limit }}"
|
||||
hx-trigger="revealed"
|
||||
hx-swap="beforeend"
|
||||
hx-target="#assets-grid"
|
||||
class="h-20 flex items-center justify-center text-gray-500 mt-4">
|
||||
Loading more...
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
<div class="bg-gray-800 border border-gray-700 rounded-lg p-12 text-center">
|
||||
<p class="text-gray-500 mb-4">No assets yet</p>
|
||||
<p class="text-gray-600 text-sm">Create content on an L1 renderer and publish it here.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
12
app/templates/auth/already_logged_in.html
Normal file
12
app/templates/auth/already_logged_in.html
Normal file
@@ -0,0 +1,12 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Already Logged In - Art-DAG{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="max-w-md mx-auto text-center">
|
||||
<div class="bg-green-900/50 border border-green-700 text-green-300 px-4 py-3 rounded-lg mb-4">
|
||||
You are already logged in as <strong>{{ user.username }}</strong>
|
||||
</div>
|
||||
<p><a href="/" class="text-blue-400 hover:text-blue-300">Go to home page</a></p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
37
app/templates/auth/login.html
Normal file
37
app/templates/auth/login.html
Normal file
@@ -0,0 +1,37 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Login - Art-DAG{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="max-w-md mx-auto">
|
||||
<h2 class="text-xl font-semibold mb-6">Login</h2>
|
||||
|
||||
<div id="login-result"></div>
|
||||
|
||||
<form hx-post="/auth/login" hx-target="#login-result" hx-swap="innerHTML" class="space-y-4">
|
||||
{% if return_to %}
|
||||
<input type="hidden" name="return_to" value="{{ return_to }}">
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
<label for="username" class="block text-sm font-medium text-gray-300 mb-2">Username</label>
|
||||
<input type="text" id="username" name="username" required
|
||||
class="w-full px-4 py-3 bg-gray-800 border border-gray-600 rounded-lg text-white focus:border-blue-500 focus:outline-none">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="password" class="block text-sm font-medium text-gray-300 mb-2">Password</label>
|
||||
<input type="password" id="password" name="password" required
|
||||
class="w-full px-4 py-3 bg-gray-800 border border-gray-600 rounded-lg text-white focus:border-blue-500 focus:outline-none">
|
||||
</div>
|
||||
|
||||
<button type="submit" class="w-full px-4 py-3 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg">
|
||||
Login
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<p class="mt-6 text-gray-400">
|
||||
Don't have an account? <a href="/auth/register" class="text-blue-400 hover:text-blue-300">Register</a>
|
||||
</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
45
app/templates/auth/register.html
Normal file
45
app/templates/auth/register.html
Normal file
@@ -0,0 +1,45 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Register - Art-DAG{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="max-w-md mx-auto">
|
||||
<h2 class="text-xl font-semibold mb-6">Register</h2>
|
||||
|
||||
<div id="register-result"></div>
|
||||
|
||||
<form hx-post="/auth/register" hx-target="#register-result" hx-swap="innerHTML" class="space-y-4">
|
||||
<div>
|
||||
<label for="username" class="block text-sm font-medium text-gray-300 mb-2">Username</label>
|
||||
<input type="text" id="username" name="username" required pattern="[a-zA-Z0-9_-]+"
|
||||
class="w-full px-4 py-3 bg-gray-800 border border-gray-600 rounded-lg text-white focus:border-blue-500 focus:outline-none">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium text-gray-300 mb-2">Email (optional)</label>
|
||||
<input type="email" id="email" name="email"
|
||||
class="w-full px-4 py-3 bg-gray-800 border border-gray-600 rounded-lg text-white focus:border-blue-500 focus:outline-none">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="password" class="block text-sm font-medium text-gray-300 mb-2">Password</label>
|
||||
<input type="password" id="password" name="password" required minlength="6"
|
||||
class="w-full px-4 py-3 bg-gray-800 border border-gray-600 rounded-lg text-white focus:border-blue-500 focus:outline-none">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="password2" class="block text-sm font-medium text-gray-300 mb-2">Confirm Password</label>
|
||||
<input type="password" id="password2" name="password2" required minlength="6"
|
||||
class="w-full px-4 py-3 bg-gray-800 border border-gray-600 rounded-lg text-white focus:border-blue-500 focus:outline-none">
|
||||
</div>
|
||||
|
||||
<button type="submit" class="w-full px-4 py-3 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg">
|
||||
Register
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<p class="mt-6 text-gray-400">
|
||||
Already have an account? <a href="/auth/login" class="text-blue-400 hover:text-blue-300">Login</a>
|
||||
</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
47
app/templates/base.html
Normal file
47
app/templates/base.html
Normal file
@@ -0,0 +1,47 @@
|
||||
{% extends "_base.html" %}
|
||||
|
||||
{% block brand %}
|
||||
<a href="https://blog.rose-ash.com/" class="no-underline text-stone-900">Rose Ash</a>
|
||||
<span class="text-stone-400 mx-1">|</span>
|
||||
<a href="/" class="no-underline text-stone-900">Art-DAG</a>
|
||||
<span class="text-stone-400 mx-1">/</span>
|
||||
<span class="text-stone-600 text-3xl">L2</span>
|
||||
{% endblock %}
|
||||
|
||||
{% block cart_mini %}
|
||||
{% if request and request.state.cart_mini_html %}
|
||||
{{ request.state.cart_mini_html | safe }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block nav_tree %}
|
||||
{% if request and request.state.nav_tree_html %}
|
||||
{{ request.state.nav_tree_html | safe }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block auth_menu %}
|
||||
{% if request and request.state.auth_menu_html %}
|
||||
{{ request.state.auth_menu_html | safe }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block auth_menu_mobile %}
|
||||
{% if request and request.state.auth_menu_html %}
|
||||
{{ request.state.auth_menu_html | safe }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block sub_nav %}
|
||||
<div class="bg-stone-200 border-b border-stone-300">
|
||||
<div class="max-w-screen-2xl mx-auto px-4">
|
||||
<nav class="flex items-center gap-4 py-2 text-sm overflow-x-auto no-scrollbar">
|
||||
<a href="/assets" class="whitespace-nowrap px-3 py-1.5 rounded {% if active_tab == 'assets' %}bg-stone-500 text-white{% else %}text-stone-700 hover:bg-stone-300{% endif %}">Assets</a>
|
||||
<a href="/activities" class="whitespace-nowrap px-3 py-1.5 rounded {% if active_tab == 'activities' %}bg-stone-500 text-white{% else %}text-stone-700 hover:bg-stone-300{% endif %}">Activities</a>
|
||||
<a href="/anchors" class="whitespace-nowrap px-3 py-1.5 rounded {% if active_tab == 'anchors' %}bg-stone-500 text-white{% else %}text-stone-700 hover:bg-stone-300{% endif %}">Anchors</a>
|
||||
<a href="/storage" class="whitespace-nowrap px-3 py-1.5 rounded {% if active_tab == 'storage' %}bg-stone-500 text-white{% else %}text-stone-700 hover:bg-stone-300{% endif %}">Storage</a>
|
||||
<a href="/renderers" class="whitespace-nowrap px-3 py-1.5 rounded {% if active_tab == 'renderers' %}bg-stone-500 text-white{% else %}text-stone-700 hover:bg-stone-300{% endif %}">Renderers</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
42
app/templates/home.html
Normal file
42
app/templates/home.html
Normal file
@@ -0,0 +1,42 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Art-DAG{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="max-w-4xl mx-auto">
|
||||
{% if readme_html %}
|
||||
<div class="prose prose-invert max-w-none mb-12">
|
||||
{{ readme_html | safe }}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-center py-12">
|
||||
<h1 class="text-4xl font-bold mb-4">Art-DAG</h1>
|
||||
<p class="text-xl text-gray-400 mb-8">Content-Addressable Media with ActivityPub Federation</p>
|
||||
|
||||
{% if not user %}
|
||||
<div class="flex justify-center space-x-4">
|
||||
<a href="/auth/login" class="bg-gray-700 hover:bg-gray-600 px-6 py-3 rounded-lg font-medium">Login</a>
|
||||
<a href="/auth/register" class="bg-blue-600 hover:bg-blue-700 px-6 py-3 rounded-lg font-medium">Register</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if activities %}
|
||||
<h2 class="text-2xl font-bold mb-4">Recent Activity</h2>
|
||||
<div class="space-y-4">
|
||||
{% for activity in activities %}
|
||||
<div class="bg-gray-800 rounded-lg p-4">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="text-blue-400">{{ activity.actor }}</span>
|
||||
<span class="text-gray-500 text-sm">{{ activity.created_at }}</span>
|
||||
</div>
|
||||
<div class="text-gray-300">
|
||||
{{ activity.type }}: {{ activity.summary or activity.object_type }}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
52
app/templates/renderers/list.html
Normal file
52
app/templates/renderers/list.html
Normal file
@@ -0,0 +1,52 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<h1 class="text-2xl font-bold mb-6">Renderers</h1>
|
||||
|
||||
<p class="text-gray-400 mb-6">
|
||||
Renderers are L1 servers that process your media. Connect to a renderer to create and run recipes.
|
||||
</p>
|
||||
|
||||
{% if error %}
|
||||
<div class="bg-red-900/50 border border-red-500 text-red-200 px-4 py-3 rounded mb-6">
|
||||
{{ error }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if success %}
|
||||
<div class="bg-green-900/50 border border-green-500 text-green-200 px-4 py-3 rounded mb-6">
|
||||
{{ success }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="space-y-4">
|
||||
{% for server in servers %}
|
||||
<div class="bg-gray-800 rounded-lg p-4 flex items-center justify-between">
|
||||
<div>
|
||||
<a href="{{ server.url }}" target="_blank" class="text-blue-400 hover:text-blue-300 font-medium">
|
||||
{{ server.url }}
|
||||
</a>
|
||||
{% if server.healthy %}
|
||||
<span class="ml-2 text-green-400 text-sm">Online</span>
|
||||
{% else %}
|
||||
<span class="ml-2 text-red-400 text-sm">Offline</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<a href="{{ server.url }}/auth?auth_token={{ user.token }}"
|
||||
class="px-3 py-1 bg-blue-600 hover:bg-blue-500 rounded text-sm">
|
||||
Connect
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="text-gray-500">No renderers configured.</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="mt-8 text-gray-500 text-sm">
|
||||
<p>Renderers are configured by the system administrator.</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
41
app/templates/storage/list.html
Normal file
41
app/templates/storage/list.html
Normal file
@@ -0,0 +1,41 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Storage - Art-DAG{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h1 class="text-2xl font-bold">Storage Providers</h1>
|
||||
<a href="/storage/add" class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-lg text-sm">
|
||||
Add Storage
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{% if storages %}
|
||||
<div class="space-y-4">
|
||||
{% for storage in storages %}
|
||||
<div class="bg-gray-800 border border-gray-700 rounded-lg p-4">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="font-medium">{{ storage.name or storage.provider_type }}</span>
|
||||
<span class="text-xs px-2 py-1 rounded {% if storage.is_active %}bg-green-600{% else %}bg-gray-600{% endif %}">
|
||||
{{ storage.provider_type }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-gray-400 text-sm">
|
||||
{% if storage.endpoint %}
|
||||
{{ storage.endpoint }}
|
||||
{% elif storage.bucket %}
|
||||
Bucket: {{ storage.bucket }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-center py-12 text-gray-400">
|
||||
<p>No storage providers configured.</p>
|
||||
<a href="/storage/add" class="text-blue-400 hover:text-blue-300 mt-2 inline-block">Add one now</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user