- standardize comment and reply UI layout - target replies with stable OOB container IDs - remove stale empty-state on approved HTMX comments - initialize Turnstile widgets after HTMX swaps - add regression tests for empty-state, OOB targets, and reply form rerender Refs #48
78 lines
3.2 KiB
HTML
78 lines
3.2 KiB
HTML
{% load static %}
|
|
<div id="reply-form-container-{{ comment.id }}">
|
|
<h4 class="mb-3 font-display text-sm font-bold uppercase tracking-wider text-zinc-700 dark:text-zinc-200">Reply to {{ comment.author_name }}</h4>
|
|
|
|
{% if reply_success_message %}
|
|
<div class="mb-4 rounded-md border border-brand-cyan/30 bg-brand-cyan/10 p-3 font-mono text-sm text-brand-cyan">
|
|
{{ reply_success_message }}
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if reply_form_errors %}
|
|
<div aria-label="Comment form errors" class="mb-4 rounded-md border border-red-500/30 bg-red-500/10 p-3 font-mono text-sm text-red-500">
|
|
<div class="mb-2 text-xs font-bold uppercase tracking-wider">Errors:</div>
|
|
<ul class="list-disc list-inside space-y-1">
|
|
{% for field, errors in reply_form_errors.items %}
|
|
{% for error in errors %}<li>{{ error }}</li>{% endfor %}
|
|
{% endfor %}
|
|
</ul>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<form
|
|
method="post"
|
|
action="{% url 'comment_post' %}"
|
|
hx-post="{% url 'comment_post' %}"
|
|
hx-target="#reply-form-container-{{ comment.id }}"
|
|
hx-swap="outerHTML"
|
|
class="space-y-3"
|
|
>
|
|
{% csrf_token %}
|
|
<input type="hidden" name="article_id" value="{{ page.id }}" />
|
|
<input type="hidden" name="parent_id" value="{{ comment.id }}" />
|
|
|
|
<div class="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
|
<input
|
|
type="text"
|
|
name="author_name"
|
|
required
|
|
placeholder="Name"
|
|
value="{% if reply_form %}{{ reply_form.author_name.value|default:'' }}{% endif %}"
|
|
class="w-full rounded-md border border-zinc-300 bg-white px-3 py-2 text-sm text-zinc-900 focus:border-brand-cyan focus:outline-none focus:ring-2 focus:ring-brand-cyan/30 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-100"
|
|
/>
|
|
<input
|
|
type="email"
|
|
name="author_email"
|
|
required
|
|
placeholder="Email"
|
|
value="{% if reply_form %}{{ reply_form.author_email.value|default:'' }}{% endif %}"
|
|
class="w-full rounded-md border border-zinc-300 bg-white px-3 py-2 text-sm text-zinc-900 focus:border-brand-cyan focus:outline-none focus:ring-2 focus:ring-brand-cyan/30 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-100"
|
|
/>
|
|
</div>
|
|
|
|
<textarea
|
|
name="body"
|
|
required
|
|
placeholder="Write your reply"
|
|
rows="3"
|
|
class="w-full rounded-md border border-zinc-300 bg-white px-3 py-2 text-sm text-zinc-900 focus:border-brand-cyan focus:outline-none focus:ring-2 focus:ring-brand-cyan/30 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-100"
|
|
>{% if reply_form %}{{ reply_form.body.value|default:'' }}{% endif %}</textarea>
|
|
|
|
<input type="text" name="honeypot" hidden />
|
|
|
|
{% if turnstile_site_key %}
|
|
<div class="cf-turnstile" data-sitekey="{{ turnstile_site_key }}" data-theme="auto" data-size="flexible"></div>
|
|
{% endif %}
|
|
|
|
<div class="flex justify-end">
|
|
<button
|
|
type="submit"
|
|
data-testid="post-reply-btn"
|
|
class="inline-flex items-center rounded-md bg-brand-pink px-4 py-2 font-display text-sm font-bold uppercase tracking-wider text-white transition hover:bg-brand-pink/90 focus:outline-none focus:ring-2 focus:ring-brand-pink/40"
|
|
>
|
|
Post reply
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|