krea-realtime-video / index.html
multimodalart's picture
Update index.html
e4169b9 verified
raw
history blame
9.94 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Real-time Video Generation</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #0f172a, #1e3a8a, #312e81);
color: #e2e8f0;
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
header {
text-align: center;
margin-bottom: 30px;
}
h1 {
font-size: 2rem;
margin-bottom: 10px;
background: linear-gradient(to right, #22d3ee, #3b82f6, #a855f7);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.subtitle {
color: #94a3b8;
font-size: 0.9rem;
}
/* Login Screen */
.login-container {
max-width: 500px;
margin: 100px auto;
background: rgba(15, 23, 42, 0.95);
backdrop-filter: blur(10px);
border-radius: 12px;
border: 1px solid rgba(148, 163, 184, 0.2);
padding: 40px;
text-align: center;
}
.login-container h2 {
margin-bottom: 20px;
color: #e2e8f0;
}
.login-container p {
color: #94a3b8;
margin-bottom: 30px;
}
.btn {
padding: 12px 24px;
border: none;
border-radius: 6px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
text-decoration: none;
display: inline-block;
}
.btn-primary {
background: #10b981;
color: white;
box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
font-size: 1rem;
}
.btn-primary:hover {
background: #059669;
}
.info-box {
background: rgba(59, 130, 246, 0.1);
border: 1px solid rgba(59, 130, 246, 0.3);
border-radius: 6px;
padding: 15px;
margin-top: 30px;
font-size: 0.85rem;
color: #93c5fd;
text-align: left;
}
.error-box {
background: rgba(239, 68, 68, 0.1);
border: 1px solid rgba(239, 68, 68, 0.3);
border-radius: 6px;
padding: 12px;
margin-top: 15px;
font-size: 0.85rem;
color: #fca5a5;
}
/* User Bar */
.user-bar {
background: rgba(15, 23, 42, 0.6);
backdrop-filter: blur(10px);
border-radius: 12px;
border: 1px solid rgba(148, 163, 184, 0.2);
padding: 15px 20px;
margin-bottom: 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
.user-info {
display: flex;
align-items: center;
gap: 15px;
}
.user-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
border: 2px solid #3b82f6;
}
.user-details h3 {
font-size: 1rem;
margin-bottom: 3px;
}
.user-badge {
display: inline-block;
padding: 2px 8px;
border-radius: 4px;
font-size: 0.7rem;
font-weight: 600;
text-transform: uppercase;
}
.badge-pro {
background: linear-gradient(135deg, #f59e0b, #d97706);
color: white;
}
.badge-free {
background: #475569;
color: #94a3b8;
}
.usage-info {
font-size: 0.85rem;
color: #94a3b8;
}
.btn-logout {
padding: 8px 16px;
background: #475569;
color: #e2e8f0;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 0.85rem;
}
.btn-logout:hover {
background: #64748b;
}
.limit-warning {
background: rgba(239, 68, 68, 0.1);
border: 1px solid rgba(239, 68, 68, 0.3);
border-radius: 12px;
padding: 20px;
margin-bottom: 20px;
text-align: center;
}
.limit-warning h3 {
color: #fca5a5;
margin-bottom: 10px;
}
.upgrade-link {
color: #3b82f6;
text-decoration: none;
font-weight: 500;
}
.upgrade-link:hover {
text-decoration: underline;
}
.hidden {
display: none;
}
@media (max-width: 768px) {
.user-bar {
flex-direction: column;
gap: 15px;
}
}
</style>
</head>
<body>
<div class="container">
{% if not authenticated %}
<!-- Login Screen -->
<div class="login-container">
<h2>πŸ€— Sign in with Hugging Face</h2>
<p>Authenticate with your Hugging Face account to start generating videos</p>
<a href="https://huggingface.co/oauth/authorize?client_id={{ oauth_client_id }}&redirect_uri=https://{{ space_host }}/oauth/callback&scope=openid%20profile&state={{ range(10000, 99999) | random }}"
class="btn btn-primary"
target="_blank">
Sign in with Hugging Face
</a>
{% if error %}
<div class="error-box">{{ error }}</div>
{% endif %}
<div class="info-box">
<strong>πŸ“Š Usage Limits:</strong><br>
β€’ <strong>Free Users:</strong> 1 session per day<br>
β€’ <strong>PRO Users:</strong> 15 sessions per day<br><br>
<small>Limits reset daily at midnight UTC</small>
</div>
</div>
{% else %}
<!-- Authenticated App -->
<div class="user-bar">
<div class="user-info">
{% if user.avatar %}
<img src="{{ user.avatar }}" alt="Avatar" class="user-avatar">
{% endif %}
<div class="user-details">
<h3>{{ user.fullname }}</h3>
<span class="user-badge {% if user.is_pro %}badge-pro{% else %}badge-free{% endif %}">
{% if user.is_pro %}PRO{% else %}FREE{% endif %}
</span>
</div>
</div>
<div style="text-align: right;">
<div class="usage-info">Sessions: {{ sessions_used }}/{{ sessions_limit }} today</div>
<button class="btn-logout" onclick="logout()">Logout</button>
</div>
</div>
{% if not can_start %}
<div class="limit-warning">
<h3>⚠️ Daily Limit Reached</h3>
<p>You've used all {{ sessions_limit }} sessions for today. Come back tomorrow!</p>
{% if not user.is_pro %}
<p style="margin-top: 10px;">
Upgrade to <a href="https://huggingface.co/pricing" target="_blank" class="upgrade-link">Hugging Face PRO</a> for 15 sessions per day!
</p>
{% endif %}
</div>
{% endif %}
<header>
<h1>Real-time Video Generation</h1>
<p class="subtitle">Self-Forcing Diffusion β€’ 832Γ—480 Resolution</p>
</header>
<div style="text-align: center; padding: 40px;">
<h2>🚧 Video Generation Interface Coming Soon</h2>
<p style="color: #94a3b8; margin-top: 10px;">
The full video generation interface will be integrated here.
</p>
{% if can_start %}
<button class="btn btn-primary" onclick="startSession()" id="testBtn" style="margin-top: 20px;">
Test Start Session
</button>
{% endif %}
<div id="statusMessage" style="margin-top: 20px;"></div>
</div>
{% endif %}
</div>
<script>
{% if authenticated %}
async function logout() {
await fetch('/api/logout', {method: 'POST'});
window.location.reload();
}
async function startSession() {
const btn = document.getElementById('testBtn');
const msg = document.getElementById('statusMessage');
btn.disabled = true;
btn.textContent = 'Starting...';
try {
const response = await fetch('/api/start-session', {method: 'POST'});
const data = await response.json();
if (response.ok) {
msg.innerHTML = `<div class="info-box">βœ“ Session started! (${data.sessions_used}/${data.sessions_limit} used today)</div>`;
btn.textContent = 'Session Active';
} else {
msg.innerHTML = `<div class="error-box">${data.detail || 'Failed to start session'}</div>`;
btn.disabled = false;
btn.textContent = 'Test Start Session';
}
} catch (error) {
msg.innerHTML = `<div class="error-box">Network error. Please try again.</div>`;
btn.disabled = false;
btn.textContent = 'Test Start Session';
}
}
{% endif %}
</script>
</body>
</html>