Initial prototype for theme song booth
This commit is contained in:
commit
c16d48ee32
16 changed files with 898 additions and 0 deletions
125
templates/admin/request.html
Normal file
125
templates/admin/request.html
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Request #{{ req.id }} — Admin</title>
|
||||
<style>
|
||||
body{font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;background:#111827;color:#f3f4f6;margin:0;padding:1rem;line-height:1.5}
|
||||
.container{max-width:900px;margin:0 auto}
|
||||
h1,h2{color:#60a5fa}
|
||||
a{color:#93c5fd}
|
||||
.section{background:#1f2937;padding:1rem;border-radius:.5rem;margin-bottom:1rem}
|
||||
label{display:block;margin-top:.8rem;font-weight:600}
|
||||
input,textarea{width:100%;padding:.6rem;border-radius:.5rem;border:1px solid #374151;background:#111827;color:#f3f4f6;box-sizing:border-box;font:inherit}
|
||||
textarea{min-height:120px}
|
||||
button{padding:.7rem 1rem;border:none;border-radius:.5rem;background:#3b82f6;color:#fff;font-weight:700;cursor:pointer;margin-top:.5rem}
|
||||
button.secondary{background:#4b5563}
|
||||
button.danger{background:#dc2626}
|
||||
button.success{background:#10b981}
|
||||
.actions{display:flex;gap:.5rem;flex-wrap:wrap;margin-top:.5rem}
|
||||
.flash{padding:.8rem;background:#064e3b;border-radius:.5rem;margin-bottom:1rem}
|
||||
.flash.error{background:#450a0a}
|
||||
.info-grid{display:grid;grid-template-columns:1fr 1fr;gap:1rem}
|
||||
.info-grid div{background:#111827;padding:.6rem;border-radius:.5rem}
|
||||
.approved-box{font-size:1.2rem;font-weight:bold;color:#fbbf24}
|
||||
.copy-hint{font-size:.85rem;color:#9ca3af;margin-top:.3rem}
|
||||
pre{background:#111827;padding:.8rem;border-radius:.5rem;overflow:auto;white-space:pre-wrap}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<p><a href="{{ url_for('admin_dashboard') }}">← Dashboard</a></p>
|
||||
<h1>Request #{{ req.id }} — {{ req.name }}</h1>
|
||||
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% for category, message in messages %}
|
||||
<div class="flash {{ category }}">{{ message }}</div>
|
||||
{% endfor %}
|
||||
{% endwith %}
|
||||
|
||||
<div class="section">
|
||||
<h2>Customer Info</h2>
|
||||
<div class="info-grid">
|
||||
<div><strong>Email:</strong> {{ req.email }}</div>
|
||||
<div><strong>Status:</strong> {{ statuses[req.status] }}</div>
|
||||
</div>
|
||||
<p><strong>Hobbies:</strong><br>{{ req.hobbies or '-' }}</p>
|
||||
<p><strong>Notable facts:</strong><br>{{ req.notable_facts or '-' }}</p>
|
||||
<p><strong>Style / genre:</strong><br>{{ req.style_genre or '-' }}</p>
|
||||
<p><strong>Extra requests:</strong><br>{{ req.extra_requests or '-' }}</p>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>1. Generate Suno Prompt</h2>
|
||||
<button type="button" onclick="copyPromptForHermes()">Copy customer info for Hermes</button>
|
||||
<p class="copy-hint">Paste the result from Hermes into the fields below, then click Save.</p>
|
||||
<form method="POST">
|
||||
<input type="hidden" name="action" value="save_prompt">
|
||||
<label for="suno_style">Suno Style</label>
|
||||
<textarea id="suno_style" name="suno_style">{{ req.suno_style or '' }}</textarea>
|
||||
<label for="suno_lyrics">Suno Lyrics (with metatags)</label>
|
||||
<textarea id="suno_lyrics" name="suno_lyrics" rows="12">{{ req.suno_lyrics or '' }}</textarea>
|
||||
<div class="actions">
|
||||
<button type="submit">Save Prompt</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>2. Upload Songs</h2>
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<input type="hidden" name="action" value="upload_songs">
|
||||
<label for="song_a">Version A MP3</label>
|
||||
<input type="file" id="song_a" name="song_a" accept="audio/mpeg,.mp3">
|
||||
<label for="song_b">Version B MP3</label>
|
||||
<input type="file" id="song_b" name="song_b" accept="audio/mpeg,.mp3">
|
||||
<div class="actions">
|
||||
<button type="submit">Upload Songs</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>3. Notify Customer</h2>
|
||||
<p>Both songs must be uploaded first.</p>
|
||||
<form method="POST">
|
||||
<input type="hidden" name="action" value="notify_customer">
|
||||
<button type="submit" {% if not (req.song_a_path and req.song_b_path) %}disabled{% endif %}>Send Preview Link</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>4. Payment & Delivery</h2>
|
||||
<p>Customer approved:
|
||||
{% if req.customer_approved == 'none' %}
|
||||
<span class="approved-box">Nothing yet</span>
|
||||
{% else %}
|
||||
<span class="approved-box">{{ req.customer_approved.upper() }}</span>
|
||||
{% endif %}
|
||||
</p>
|
||||
<form method="POST">
|
||||
<input type="hidden" name="action" value="mark_paid_deliver">
|
||||
<label for="square_payment_ref">Square Payment Reference</label>
|
||||
<input type="text" id="square_payment_ref" name="square_payment_ref" placeholder="e.g. sq0idp-... or receipt number">
|
||||
<div class="actions">
|
||||
<button type="submit" class="success" {% if req.customer_approved == 'none' %}disabled{% endif %}>Mark Paid & Deliver</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function copyPromptForHermes() {
|
||||
const data = {
|
||||
name: {{ req.name | tojson }},
|
||||
hobbies: {{ req.hobbies | tojson }},
|
||||
notable_facts: {{ req.notable_facts | tojson }},
|
||||
style_genre: {{ req.style_genre | tojson }},
|
||||
extra_requests: {{ req.extra_requests | tojson }}
|
||||
};
|
||||
const text = "Please write a Suno Custom Mode prompt for this customer. Return ONLY a JSON object with keys: title, style, lyrics.\n\nCustomer data:\n" + JSON.stringify(data, null, 2);
|
||||
navigator.clipboard.writeText(text).then(() => alert("Copied! Paste into Hermes, then paste Hermes JSON result back into the Style/Lyrics fields."));
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in a new issue