Add required pronouns dropdown and fix admin vocal gender selector
- Added a required Pronouns dropdown to /request and /admin/request: He/Him/His, She/Her/Hers, They/Them/Their. - Moved Email to the top of the customer request form; Pronouns sit just below Name. - Added column to the requests schema with automatic migration. - Stored pronouns are included in confirmation emails and Hermes prompt copy. - Fixed /admin/request so Preferred singer voice / gender is a dropdown matching the customer form instead of a free-text input. - Updated README to describe pronouns and the structured style selectors. Bumps version to 0.4.7.
This commit is contained in:
parent
10ee182558
commit
3f7bbf4b12
6 changed files with 65 additions and 17 deletions
|
|
@ -176,6 +176,14 @@
|
|||
<label for="customer_name">Name / persona</label>
|
||||
<input type="text" id="customer_name" name="name" value="{{ req.name }}" required>
|
||||
|
||||
<label for="customer_pronouns">Pronouns <span style="color:#f87171">*</span></label>
|
||||
<select id="customer_pronouns" name="pronouns" required>
|
||||
<option value="" {% if not req.pronouns %}selected{% endif %}>— Select pronouns —</option>
|
||||
<option value="He/Him/His" {% if req.pronouns == 'He/Him/His' %}selected{% endif %}>He/Him/His</option>
|
||||
<option value="She/Her/Hers" {% if req.pronouns == 'She/Her/Hers' %}selected{% endif %}>She/Her/Hers</option>
|
||||
<option value="They/Them/Their" {% if req.pronouns == 'They/Them/Their' %}selected{% endif %}>They/Them/Their</option>
|
||||
</select>
|
||||
|
||||
<label for="customer_hobbies">Hobbies & interests</label>
|
||||
<textarea id="customer_hobbies" name="hobbies" rows="3">{{ req.hobbies or '' }}</textarea>
|
||||
|
||||
|
|
@ -209,7 +217,14 @@
|
|||
<p style="font-size:.85rem;color:#9ca3af;margin-top:.3rem">Stored style: {{ req.style_genre or '—' }}</p>
|
||||
|
||||
<label for="customer_vocal_gender">Preferred singer voice / gender</label>
|
||||
<input type="text" id="customer_vocal_gender" name="vocal_gender" value="{{ req.vocal_gender or '' }}">
|
||||
<select id="customer_vocal_gender" name="vocal_gender">
|
||||
<option value="" {% if not req.vocal_gender %}selected{% endif %}>No preference</option>
|
||||
<option value="female" {% if req.vocal_gender == 'female' %}selected{% endif %}>Female</option>
|
||||
<option value="male" {% if req.vocal_gender == 'male' %}selected{% endif %}>Male</option>
|
||||
<option value="non-binary" {% if req.vocal_gender == 'non-binary' %}selected{% endif %}>Non-binary / Gender-neutral</option>
|
||||
<option value="androgynous" {% if req.vocal_gender == 'androgynous' %}selected{% endif %}>Androgynous</option>
|
||||
<option value="other" {% if req.vocal_gender == 'other' %}selected{% endif %}>Other (mention in Extra Requests)</option>
|
||||
</select>
|
||||
|
||||
<label for="customer_extra_requests">Anything else</label>
|
||||
<textarea id="customer_extra_requests" name="extra_requests" rows="3">{{ req.extra_requests or '' }}</textarea>
|
||||
|
|
@ -440,13 +455,14 @@
|
|||
request_id: {{ req.id | tojson }},
|
||||
email: {{ req.email | tojson }},
|
||||
name: {{ req.name | tojson }},
|
||||
pronouns: {{ req.pronouns | tojson }},
|
||||
hobbies: {{ req.hobbies | tojson }},
|
||||
notable_facts: {{ req.notable_facts | tojson }},
|
||||
style_genre: styleGenre,
|
||||
vocal_gender: {{ req.vocal_gender | tojson }},
|
||||
extra_requests: {{ req.extra_requests | tojson }}
|
||||
};
|
||||
const text = `Booth request: ${data.request_id}\\nCustomer email: ${data.email}\\nCallback URL: ${callbackUrl}\\n\\nGenerate a Suno Custom Mode prompt for this customer and POST it back to the Callback URL as JSON.\\n\\nCustomer data:\\nName: ${data.name}\\nHobbies: ${data.hobbies || '-'}\\nNotable facts: ${data.notable_facts || '-'}\\nStyle / genre: ${styleSentence || styleGenre || '-'}\\nPreferred singer voice / gender: ${data.vocal_gender || 'No preference'}\\nExtra requests: ${data.extra_requests || '-'}\\n\\nExpected JSON response format:\\n{\\n \\"request_id\\": ${data.request_id},\\n \\"email\\": \\"${data.email}\\",\\n \\"suno_title\\": \\"...\\",\\n \\"suno_style\\": \\"...\\",\\n \\"suno_lyrics\\": \\"...\\"\\n}`;
|
||||
const text = `Booth request: ${data.request_id}\\nCustomer email: ${data.email}\\nCallback URL: ${callbackUrl}\\n\\nGenerate a Suno Custom Mode prompt for this customer and POST it back to the Callback URL as JSON.\\n\\nCustomer data:\\nName: ${data.name}\\nPronouns: ${data.pronouns || '-'}\\nHobbies: ${data.hobbies || '-'}\\nNotable facts: ${data.notable_facts || '-'}\\nStyle / genre: ${styleSentence || styleGenre || '-'}\\nPreferred singer voice / gender: ${data.vocal_gender || 'No preference'}\\nExtra requests: ${data.extra_requests || '-'}\\n\\nExpected JSON response format:\\n{\\n \\"request_id\\": ${data.request_id},\\n \\"email\\": \\"${data.email}\\",\\n \\"suno_title\\": \\"...\\",\\n \\"suno_style\\": \\"...\\",\\n \\"suno_lyrics\\": \\"...\\"\\n}`;
|
||||
navigator.clipboard.writeText(text).then(() => alert("Copied! Paste into Hermes. Hermes will POST the generated prompt back to the Callback URL."));
|
||||
}
|
||||
|
||||
|
|
@ -474,13 +490,14 @@
|
|||
request_id: {{ req.id | tojson }},
|
||||
email: {{ req.email | tojson }},
|
||||
name: {{ req.name | tojson }},
|
||||
pronouns: {{ req.pronouns | tojson }},
|
||||
hobbies: {{ req.hobbies | tojson }},
|
||||
notable_facts: {{ req.notable_facts | tojson }},
|
||||
style_genre: styleGenre,
|
||||
vocal_gender: {{ req.vocal_gender | tojson }},
|
||||
extra_requests: {{ req.extra_requests | tojson }}
|
||||
};
|
||||
const text = `Booth request: ${data.request_id}\\nCustomer email: ${data.email}\\nCallback URL: ${callbackUrl}\\n\\nThis is REVISION #${revisionCount || 1} for this customer.\\n\\nGenerate a NEW Suno Custom Mode prompt that addresses the following revision request, while keeping the same overall theme/persona and matching the customer's original brief as closely as possible.\\n\\nOriginal brief:\\nName: ${data.name}\\nHobbies: ${data.hobbies || '-'}\\nNotable facts: ${data.notable_facts || '-'}\\nStyle / genre: ${styleSentence || styleGenre || '-'}\\nPreferred singer voice / gender: ${data.vocal_gender || 'No preference'}\\nExtra requests: ${data.extra_requests || '-'}\\n\\nPreviously generated prompt (do not copy verbatim; adapt and improve):\\nTitle: ${currentTitle || '-'}\\nStyle: ${currentStyle || '-'}\\nLyrics:\\n${currentLyrics || '-'}\\n\\nRevision request from customer:\\n${revisionNote || '-'}\\n\\nPOST the new prompt back to the Callback URL as JSON with this shape:\\n{\\n \\"request_id\\": ${data.request_id},\\n \\"email\\": \\"${data.email}\\",\\n \\"suno_title\\": \\"...\\",\\n \\"suno_style\\": \\"...\\",\\n \\"suno_lyrics\\": \\"...\\"\\n}`;
|
||||
const text = `Booth request: ${data.request_id}\\nCustomer email: ${data.email}\\nCallback URL: ${callbackUrl}\\n\\nThis is REVISION #${revisionCount || 1} for this customer.\\n\\nGenerate a NEW Suno Custom Mode prompt that addresses the following revision request, while keeping the same overall theme/persona and matching the customer's original brief as closely as possible.\\n\\nOriginal brief:\\nName: ${data.name}\\nPronouns: ${data.pronouns || '-'}\\nHobbies: ${data.hobbies || '-'}\\nNotable facts: ${data.notable_facts || '-'}\\nStyle / genre: ${styleSentence || styleGenre || '-'}\\nPreferred singer voice / gender: ${data.vocal_gender || 'No preference'}\\nExtra requests: ${data.extra_requests || '-'}\\n\\nPreviously generated prompt (do not copy verbatim; adapt and improve):\\nTitle: ${currentTitle || '-'}\\nStyle: ${currentStyle || '-'}\\nLyrics:\\n${currentLyrics || '-'}\\n\\nRevision request from customer:\\n${revisionNote || '-'}\\n\\nPOST the new prompt back to the Callback URL as JSON with this shape:\\n{\\n \\"request_id\\": ${data.request_id},\\n \\"email\\": \\"${data.email}\\",\\n \\"suno_title\\": \\"...\\",\\n \\"suno_style\\": \\"...\\",\\n \\"suno_lyrics\\": \\"...\\"\\n}`;
|
||||
navigator.clipboard.writeText(text).then(() => alert("Revision prompt copied! Paste into Hermes. Hermes will POST the revised prompt back to the Callback URL."));
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
Reference in a new issue