Removed redundant Analityka button since charts auto-load on page load.
"Odswiez wszystkie" now also renders charts after fetching.
Two buttons remain: "Najnowsze 10" (quick preview) and "Odswiez wszystkie"
(full fetch + cache + charts).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Charts now render automatically on page load via AJAX from DB cache
(no click needed). Info bar above charts shows post count, cache date,
and hint to refresh. GET cache endpoint now returns cached_at date.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Facebook Graph API can return cycling cursors causing infinite fetch loops.
Added: post ID deduplication, seen-cursor detection, max 100 pages limit.
Applied to both loadAllFbPosts and refreshAllFbPosts functions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shows clear instructions: if cache has more posts than displayed,
guide to Analityka. If cache is small (10 posts), guide to
"Odswiez wszystkie" first, then Analityka.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
"Najnowsze 10" no longer saves to DB cache.
New "Odswiez wszystkie" button fetches all posts via FB API pagination
and saves to cache. "Analityka" uses cache for instant charts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fixes slow page load for non-admin users (919KB inline JSON).
Route now sends max 10 posts inline with total_count metadata.
New GET endpoint serves full cache via AJAX for Analityka button.
loadAllFbPosts tries DB cache first (instant), falls back to FB API.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Admin's _get_user_company_ids returns None meaning all companies,
but iterating over None gave empty list. Now falls back to fb_stats keys.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Migration 071: Add cached_posts (JSONB) and posts_cached_at to social_media_config
- Service: get_cached_posts() and save_all_posts_to_cache() methods
- Route: New POST endpoint to save posts cache, pass cached data to template
- Template: Render cached posts+charts instantly on page load from DB,
save to DB after "Load all" or "Refresh", remove AJAX auto-load
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Posts now appear immediately when visiting Social Media Dashboard
instead of requiring manual button click.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shortened nav label to fit single line, added rotated gradient beta badge.
Moved nav position from after Edukacja to between Forum and Aktualnosci.
Updated admin sidebar label to Social Dashboard with beta badge.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New charts: post types (doughnut), best day of week (bar with dual axis),
best hour (bar with dual axis), top 5 posts (stacked horizontal bar).
Replace redundant likes metric with weighted engagement score per post.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously get_page_posts returned a flat list with no pagination support.
Now returns dict with posts and next_cursor, enabling infinite scrolling
through all Facebook page posts via the after query parameter.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds auto-pagination that fetches all Facebook posts and renders 3 Chart.js
visualizations: engagement per post (line), publication activity per month (bar),
and average engagement trend per month (line with fill).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Display last 10 posts from connected Facebook page with engagement
data (likes, comments, shares, reactions). On-demand insights button
loads impressions, reach, engaged users, and clicks per post.
In-memory cache with 5-min TTL prevents API rate limit issues.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Expandable help section on Integracje page explaining when connection
may stop working (password change, app removal, role loss)
- Troubleshooting link on Social Publisher stats panel
- Actionable error message on failed posts pointing to Integracje
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- select-page now saves page token to SocialMediaConfig.access_token
- _get_publish_token prefers config page token over OAuthToken
- Prevents breakage when OAuth reconnect overwrites OAuthToken with USER token
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add 'failed' to allowed statuses in publish_post() and update_post()
- Show "Spróbuj ponownie" button for failed posts in form template
- Root cause: select-page endpoint stored USER token instead of PAGE token
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Social Publisher: blue gradient panel with followers, engagement,
completeness, contact pills, and refresh button.
Integracje: "Synchronizuj dane" button next to Disconnect for Facebook.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Batch-query confirmed attendee counts per event and display as
subtle cyan number with people icon in event meta line.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Single company: links directly to company profile.
Multiple companies: opens picker modal with company list.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Graph API returns link as facebook.com/123456 even when a vanity URL
exists. Skip API link when it contains only digits after facebook.com/.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Store extra Graph API fields in content_types JSONB. Show category tag,
contact pills with icons, and description in styled quote block.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Don't overwrite vanity URL with numeric page_id fallback
- Display profile description and completeness bar on Facebook card
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After connecting a FB page via OAuth, automatically fetch page stats
(followers, engagement, bio) from Graph API and persist to
CompanySocialMedia table. Adds manual refresh endpoint and UI badge.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Same bug as discover-pages: select-page was using page token to call
me/accounts, which returns empty. Now uses user_access_token from
metadata_json.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
OAuth integrations page was hardcoded to maciej.pienczyn@inpi.pl.
Now accessible to any user with MANAGER role or higher.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After selecting a FB page, the user token was overwritten with page
token. me/accounts requires user token to list pages, so page discovery
returned empty. Now stores user_access_token in oauth metadata_json.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rebranded user-facing labels only (menu, titles, headings).
Internal endpoint names and file names remain unchanged.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Visual flow chart showing draft -> debug -> live states with color-coded
nodes, arrows, and return path explanation. Collapsible to avoid clutter.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds warning box explaining that Facebook doesn't allow unpublishing,
contextual status badges, and dark red withdraw button to clearly
indicate destructive/irreversible action.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Facebook Graph API returns error 100 when setting is_published=false on
already-published posts. Replaced "Zmień na debug" with "Usuń z Facebooka"
which deletes the post from FB and resets status to draft for re-publishing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Nested HTML forms are invalid - browsers ignore inner form tags, so
submit() on toggleVisibilityForm did nothing. Moved toggle section
after </form> closure of postForm.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Custom confirmation modal matching portal UX with icon, title, message
and styled action buttons. Replaces all browser confirm() dialogs for
toggle visibility, publish live, and delete actions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds bidirectional visibility control: published posts can be switched
between public (live) and draft (debug/admin-only) mode via Facebook
Graph API. Includes is_live column, status indicator, and toggle buttons.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New force_live parameter in publish_post() overrides config.debug_mode
- Red "Publikuj na żywo" button with confirmation dialog
- Visible when company has debug_mode enabled
- Works for new posts, drafts, and re-publishing debug-published posts
- "Publikuj teraz" shows "(debug)" label when in debug mode
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Query company_social_media table for valid profiles (Facebook, Instagram,
LinkedIn, YouTube, etc.) and pass them as context to AI prompts.
Member spotlight posts now include social media links at the end.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pass user_id, company_id, and feature name to generate_text() calls:
- 'social_publisher_content' for post content generation
- 'social_publisher_hashtags' for hashtag generation
All costs logged to AIUsageLog and AIAPICostLog with user/company context.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace 6 generic tones with 10 research-backed options optimized for
chamber of commerce Facebook content. New default: "Opowieść" (Storytelling).
New tones: Duma i wspólnota, Rozmowa, Świętowanie, Za kulisami,
Z przymrużeniem oka. Based on Buffer/Hootsuite/Jasper best practices
and 2026 social media trends favoring authenticity over polish.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two render_template calls were missing ai_models/default_ai_model
causing UndefinedError on template render (500 error).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3 models available: Gemini 3 Flash (default, cheap), Gemini 3 Pro
(best quality, 4x cost), Gemini 2.5 Flash (stable previous gen).
Model selection applies to both content and hashtag generation.
Shows which model was used after generation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove hashtag instructions from AI prompts (content-only generation)
- Add _split_hashtags() to extract any hashtags AI still includes
- generate_content() now returns (content, hashtags, model) tuple
- Prevents duplicate hashtags when publishing (content + hashtags field)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>