Admin panel module for publishing posts on NORDA chamber Facebook page. Includes AI content generation (Gemini), post workflow (draft/approved/ scheduled/published), Facebook Graph API publishing, and engagement tracking. New: migration 070, SocialPost/SocialMediaConfig models, publisher service, admin routes with AJAX, 3 templates (list/form/settings). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
215 lines
7.0 KiB
HTML
215 lines
7.0 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Ustawienia Social Publisher - Norda Biznes Partner{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<style>
|
|
.admin-header {
|
|
margin-bottom: var(--spacing-xl);
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.admin-header h1 {
|
|
font-size: var(--font-size-3xl);
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.form-section {
|
|
background: var(--surface);
|
|
padding: var(--spacing-xl);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow);
|
|
max-width: 700px;
|
|
margin-bottom: var(--spacing-xl);
|
|
}
|
|
|
|
.form-group {
|
|
margin-bottom: var(--spacing-lg);
|
|
}
|
|
|
|
.form-group label {
|
|
display: block;
|
|
margin-bottom: var(--spacing-xs);
|
|
font-weight: 500;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.form-group input[type="text"],
|
|
.form-group textarea {
|
|
width: 100%;
|
|
padding: var(--spacing-sm) var(--spacing-md);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
font-size: var(--font-size-base);
|
|
font-family: inherit;
|
|
}
|
|
|
|
.form-group textarea {
|
|
min-height: 80px;
|
|
resize: vertical;
|
|
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
|
|
.form-hint {
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-secondary);
|
|
margin-top: var(--spacing-xs);
|
|
}
|
|
|
|
.checkbox-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-xs);
|
|
}
|
|
|
|
.checkbox-item input[type="checkbox"] {
|
|
width: 18px;
|
|
height: 18px;
|
|
}
|
|
|
|
.btn-group {
|
|
display: flex;
|
|
gap: var(--spacing-md);
|
|
margin-top: var(--spacing-xl);
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.info-box {
|
|
background: var(--surface);
|
|
padding: var(--spacing-xl);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow);
|
|
max-width: 700px;
|
|
margin-bottom: var(--spacing-xl);
|
|
}
|
|
|
|
.info-box h2 {
|
|
font-size: var(--font-size-xl);
|
|
margin-bottom: var(--spacing-md);
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.info-box ol {
|
|
padding-left: var(--spacing-lg);
|
|
color: var(--text-secondary);
|
|
line-height: 1.8;
|
|
}
|
|
|
|
.info-box ol li {
|
|
margin-bottom: var(--spacing-xs);
|
|
}
|
|
|
|
.config-status {
|
|
background: var(--background);
|
|
padding: var(--spacing-md);
|
|
border-radius: var(--radius);
|
|
margin-bottom: var(--spacing-lg);
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
|
|
.config-status strong {
|
|
color: var(--primary);
|
|
}
|
|
|
|
.config-status .status-active {
|
|
color: var(--success);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.config-status .status-inactive {
|
|
color: var(--error);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.section-title {
|
|
font-size: var(--font-size-lg);
|
|
font-weight: 600;
|
|
color: var(--text-primary);
|
|
margin-bottom: var(--spacing-md);
|
|
padding-bottom: var(--spacing-xs);
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container">
|
|
<div class="admin-header">
|
|
<h1>Ustawienia Social Publisher</h1>
|
|
<a href="{{ url_for('admin.social_publisher_list') }}" class="btn btn-secondary">Powrot do listy</a>
|
|
</div>
|
|
|
|
{% if config %}
|
|
<div class="config-status">
|
|
<strong>Obecna konfiguracja:</strong>
|
|
Strona: <strong>{{ config.page_name or 'Nie ustawiona' }}</strong>
|
|
| Status: {% if config.is_active %}<span class="status-active">Aktywna</span>{% else %}<span class="status-inactive">Nieaktywna</span>{% endif %}
|
|
| Debug: {% if config.debug_mode %}<span style="color: var(--warning); font-weight: 600;">Wlaczony</span>{% else %}Wylaczony{% endif %}
|
|
{% if config.updated_at %}
|
|
| Ostatnia aktualizacja: {{ config.updated_at.strftime('%Y-%m-%d %H:%M') }}
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="form-section">
|
|
<h3 class="section-title">Konfiguracja Facebook</h3>
|
|
<form method="POST">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
|
|
|
<div class="form-group">
|
|
<label for="page_id">Page ID</label>
|
|
<input type="text" id="page_id" name="page_id"
|
|
value="{{ config.page_id if config else '' }}"
|
|
placeholder="np. 123456789012345">
|
|
<p class="form-hint">Numeryczny identyfikator strony na Facebooku</p>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="page_name">Nazwa strony</label>
|
|
<input type="text" id="page_name" name="page_name"
|
|
value="{{ config.page_name if config else '' }}"
|
|
placeholder="np. Norda Biznes Partner">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="access_token">Page Access Token</label>
|
|
<textarea id="access_token" name="access_token"
|
|
placeholder="Wklej Page Access Token...">{{ config.access_token if config else '' }}</textarea>
|
|
<p class="form-hint">Token dostepu do strony FB (nie udostepniaj nikomu)</p>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="checkbox-item">
|
|
<input type="checkbox" name="debug_mode"
|
|
{% if config and config.debug_mode %}checked{% endif %}>
|
|
<span>Tryb debug</span>
|
|
</label>
|
|
<p class="form-hint">W trybie debug posty sa widoczne tylko dla adminow strony FB (nie sa publiczne)</p>
|
|
</div>
|
|
|
|
<div class="btn-group">
|
|
<a href="{{ url_for('admin.social_publisher_list') }}" class="btn btn-secondary">Anuluj</a>
|
|
<button type="submit" class="btn btn-primary">Zapisz ustawienia</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="info-box">
|
|
<h2>Jak uzyskac Page Access Token?</h2>
|
|
<ol>
|
|
<li>Przejdz do <a href="https://developers.facebook.com/" target="_blank">Facebook Developers</a> i zaloguj sie</li>
|
|
<li>Utworz aplikacje (typ: Business) lub wybierz istniejaca</li>
|
|
<li>Dodaj produkt "Facebook Login for Business"</li>
|
|
<li>Przejdz do <a href="https://developers.facebook.com/tools/explorer/" target="_blank">Graph API Explorer</a></li>
|
|
<li>Wybierz swoja aplikacje i wygeneruj User Token z uprawnieniami:
|
|
<code>pages_manage_posts</code>, <code>pages_read_engagement</code>, <code>pages_show_list</code></li>
|
|
<li>Zamien User Token na Page Token: <code>GET /me/accounts</code> - skopiuj <code>access_token</code> dla wlasciwej strony</li>
|
|
<li>Opcjonalnie: przedluz token na dlugotrwaly (60 dni) przez endpoint <code>/oauth/access_token</code></li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|