Files
monica_site/site/social/templates/social/post_detail.html
T
westfarn e8611ef926
Deploy Beta / unit-tests (push) Successful in 16s
Deploy Beta / docker (push) Successful in 20s
Deploy Beta / deploy-beta (push) Successful in 3m11s
Social composer: send now and rename messy account names (#6)
## Summary
Closes #5.
- Composer can **Send now** without a schedule time (Schedule and Save draft still available)
- Account names wrap and show the platform id so a bad OAuth label is still readable
- Social accounts page can rename the display name; re-auth keeps a custom name instead of overwriting it with a placeholder
- Worker polls `dispatch_due` every 15s so scheduled campaigns and social posts fire without a manual command; local `docker compose up` now starts the worker

## Test plan
- [ ] Open Social → Compose: confirm **Send now**, **Schedule**, and **Save draft** buttons (no combined Save / publish)
- [ ] Send now with a connected account and caption → post queues immediately, no datetime required
- [ ] Schedule with a datetime → post is scheduled; Schedule with a blank time → validation error
- [ ] Composer account list shows full name plus external id, wrapping if the name is long
- [ ] Social accounts → rename a messy label → new name shows in composer without reconnecting
- [ ] Re-authorize an account that was renamed → custom name is kept
- [ ] Rebuild and start compose (`docker compose up --build`) so the **worker** service is running
- [ ] Schedule a social post ~2 minutes ahead → after due time, worker logs `Enqueued N due item(s).` and the post leaves Scheduled (published or failed)
- [ ] `docker compose logs -f worker` shows `Polling due scheduled work every 15s.`

Reviewed-on: #6
2026-08-24 09:47:58 -07:00

59 lines
2.3 KiB
HTML

{% extends "portal_base.html" %}
{% block title %}Post · Portal{% endblock %}
{% block topbar_title %}Social post{% endblock %}
{% block portal_content %}
<div class="toolbar">
<span class="badge badge-{{ post.status }}">{{ post.get_status_display }}</span>
<a class="btn btn-sm btn-ghost" href="{% url 'social:post_list' %}">← All posts</a>
</div>
<div class="split">
<div class="panel">
<div class="panel-h"><h2>Caption</h2></div>
<div class="panel-b">
{% if post.media %}
<div style="display:flex;flex-wrap:wrap;gap:10px;margin-bottom:12px">
{% for item in post.media %}
{% if item.type == "video" %}
<video src="{{ item.url }}" controls playsinline style="max-width:100%;max-height:280px;border-radius:8px"></video>
{% else %}
<img src="{{ item.url }}" alt="{{ item.filename|default:'Image' }}" style="max-width:100%;max-height:280px;border-radius:8px;object-fit:contain">
{% endif %}
{% endfor %}
</div>
{% endif %}
<div class="preview-pane" style="white-space:pre-wrap">{{ post.body }}</div>
{% if post.scheduled_for %}
<p class="hint-block">Scheduled {{ post.scheduled_for|date:"M j, Y g:i A" }}</p>
{% endif %}
{% if post.ollama_prompt %}
<p class="hint-block">AI prompt: {{ post.ollama_prompt }}</p>
{% endif %}
</div>
</div>
<div class="panel">
<div class="panel-h"><h2>Targets</h2></div>
<div class="panel-b" style="padding:0">
<table class="table">
<thead><tr><th>Account</th><th>Platform</th><th>Status</th></tr></thead>
<tbody>
{% for target in post.targets.all %}
<tr>
<td>
{{ target.account.display_name }}
{% if target.account.external_id %}
<br><span class="muted" style="overflow-wrap:anywhere">{{ target.account.external_id }}</span>
{% endif %}
</td>
<td>{{ target.get_platform_display }}</td>
<td><span class="badge badge-{{ target.status }}">{{ target.get_status_display }}</span></td>
</tr>
{% empty %}
<tr><td colspan="3" class="empty-state">No targets attached.</td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}