Add position: sticky, top: 0, height: 100dvh to aside on desktop.
Sidebar now stays fixed to viewport height, nav scrolls internally,
user card is always visible at the bottom without scrolling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add Social, Link Affiliati, Commenti as tabs in Settings page
- Import and render existing components directly (they have their own headers)
- Sections accessible via /settings?tab=social, ?tab=affiliati, ?tab=commenti
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sidebar reorganized from 9 flat items to 7 items in 3 groups:
CREA: Genera, Libreria, Idee
PIANIFICA: Calendario, Programmati
GESTISCI: Personaggi
Removed from primary nav:
- Link Affiliati (secondary, move to Settings later)
- Social (setup, accessible via Settings)
- Commenti (unused, future Pro feature)
Other changes:
- /content/library route added (replaces /content/archive as primary)
- /content/archive kept as fallback route
- All links updated to point to /content/library
- "Contenuti" renamed to "Genera"
- "Pianificazione" renamed to "Calendario"
- "Schedulazione" renamed to "Programmati"
- "Nuovo piano" button removed from Dashboard
- Nav group headers with uppercase labels
- end prop on /content to avoid highlighting on /content/library
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SQLAlchemy doesn't detect in-place mutations on JSON columns (same object
reference). Fixed all JSON write operations to create new list/dict objects:
- save_idea: [new_idea] + old_ideas instead of ideas.insert()
- delete_idea: new filtered list
- mark_idea_used: new list with copied dicts
- approve_post: dict(examples) for content_rules
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Dashboard: track saved ideas in React state (Set), compare against
suggestion texts to show "✓ Salvata" persistently
- Backend: append 'Z' to saved_at ISO timestamp so JS parses as UTC
(fixes "2h fa" bug for UTC+2 users)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend:
- Suggestions cached in DB per user, regenerated only after 24h
- ?force=true parameter to regenerate on demand
- New endpoints: GET/POST/DELETE /content/ideas for saved ideas
- POST /content/ideas/{id}/mark-used to track usage
Frontend:
- Dashboard: suggestions loaded from cache, not regenerated on every visit
- Dashboard: "Salva idea" button on each suggestion card
- Dashboard: "Dammi altri suggerimenti" CTA to force regeneration
- Dashboard: removed "Piani Attivi" stat card
- SavedIdeas page: list saved ideas, add new, delete, generate from idea
- Sidebar: added "Idee" nav item after "Contenuti"
- App.jsx: added /ideas route
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- CharacterList: entire card is clickable to enter edit mode
- CharacterList: uses ConfirmModal for delete (replaces browser confirm)
- CharacterList: action buttons stop propagation to avoid double-nav
- ContentPage: auto-selects first active character as default
- Rename "Archivio Contenuti" → "Libreria Contenuti" everywhere
- Mobile-safe grid for character cards
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Landing Page:
- Public landing page at /landing with hero, features grid, CTA
- ProtectedRoute redirects to /landing instead of /login when not auth'd
- Editorial Fresh design: Fraunces headings, clamp() responsive sizing
Schedule Action:
- "Schedula" button appears after approving a post
- ScheduleModal: date/time picker, creates ScheduledPost via API
- Reminder to connect social accounts for automatic publishing
Editorial Calendar LLM:
- Backend: generate-calendar now calls LLM to generate hook + brief for each slot
- Uses character profile (voice, target, niche) for contextual ideas
- Respects brief strategico from the UI
- Frontend: slots show AI-generated hook (Fraunces serif) + brief description
- Each slot has "Genera contenuto →" link for one-click content generation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mobile UX:
- index.css: comprehensive mobile media queries — headings scale down,
touch targets enforced, grid-2col-mobile collapse class, tablet breakpoint
- ContentArchive/ContentPage: grid minmax uses min(100%, Npx) to prevent
overflow on small screens
- CharacterForm: visual style + rules editor grids collapse on mobile
- Dashboard: stat cards grid mobile-safe
- Layout: better nav touch targets, footer responsive gap
Phase C — One-Click Generation:
- Backend: GET /api/content/suggestions endpoint — LLM generates 3 topic
ideas based on character profile and avoids repeating recent posts
- Dashboard: "Suggerimenti per oggi" section loads suggestions on mount,
each card links to /content with prefilled topic + character
- ContentPage: reads ?topic= and ?character= URL params, auto-fills form
and auto-triggers generation (one-click flow from Dashboard)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Approve action saves post as reference example in character's content_rules
- Keep last 5 approved examples per character (auto-rotating)
- Inject last 3 approved examples as few-shot in LLM system prompt
- Lock YouTube/TikTok hashtag profile tabs for Freemium users (Pro only)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend:
- Character model: add brand_voice, target_audience, business_goals,
products_services, content_rules (JSON do/dont), hashtag_profiles (JSON)
- Content generation: inject full character context into LLM system prompt
(voice, audience, goals, products, rules)
- Hashtag generation: merge always-on tags from profile with AI-generated tags
- Schema: update CharacterBase and CharacterUpdate with new fields
Frontend:
- CharacterForm: new sections "Identità e Voce", "Regole Contenuti",
"Profili Hashtag" with dedicated editors
- RulesEditor: do/don't list with add/remove
- HashtagProfileEditor: per-platform tabs, fixed hashtags + max generated count
- All fields loaded on edit, saved on submit
DB migration: 6 new columns added to characters table
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Hide 'per facebook' badge when multiple platform tabs are visible
- Sort platforms in canonical order (Instagram, Facebook, YouTube, TikTok)
regardless of click order, for consistency between form and preview
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend:
- Add batch_id column to Post model (UUID, groups posts from same generation)
- Set batch_id in /generate endpoint for all posts in same request
Frontend:
- ContentArchive: group posts by batch_id into single cards with platform tabs
- Character name at top, platform tabs below, status badge, text preview
- Click platform tab to switch between variants of same content
- ConfirmModal: render via React portal to document.body for true fullscreen overlay
- Add box-shadow and higher z-index for better visual separation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend:
- /generate now returns array of posts (one per platform selected)
- Each post generated with platform-specific LLM prompt and char limits
- Monthly counter incremented by number of platforms
Frontend:
- ConfirmModal: reusable Editorial Fresh modal replaces ugly browser confirm()
- ContentPage: platform tabs when multiple posts, switch between variants
- ContentPage: generatedPosts array state replaces single generated
- ContentArchive: uses ConfirmModal for delete confirmation
- Platform chips filtered by plan (Freemium: IG/FB only)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Hashtag auto-save: debounced 500ms save on add/remove/edit, no manual button
- Platform chips: Freemium sees only Instagram/Facebook, Pro sees all 4
- Platform badge: changed from tab-like to informative "per instagram" label
- Add "Archivio →" link in content page header
- Rewrite ContentArchive: show text_content preview (was showing only hashtags),
add edit button, use Editorial Fresh design system, fix post.text → post.text_content
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add explicit instruction to LLM: never write framework labels (PROBLEMA,
AGITAZIONE, SOLUZIONE, etc.) — use them as invisible narrative structure only
- Replace static hashtag chips with HashtagEditor component:
- Click hashtag to edit inline
- Click X to remove
- Input field to add new hashtags
- Save button to persist changes to DB
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Opus 4.6 first, then Sonnet 4.6, Haiku 4.5
- Add legacy 4.5 Sonnet/Haiku, remove obsolete 3.5 versions
- Fix OpenRouter Claude labels to match
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add curated model catalogs for Claude, OpenAI, Gemini, OpenRouter
- ModelSelector component: dropdown with known models + "Personalizzato" option
- Custom input fallback for unknown providers or manual model IDs
- Auto-switch between dropdown/custom based on provider change
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Change default activeSection from 'piano' to 'profilo'
- Support ?tab= query param to deep-link into settings sections
- Update missing API key banner to link to /settings?tab=ai
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add 'brief' field to GenerateContentRequest schema
- Pass brief from router to generate_post_text service
- Inject brief as mandatory instructions in LLM prompt with highest priority
- Return structured error when LLM provider/API key not configured
- Show dedicated warning banner with link to Settings when API key missing
Fixes: content ignoring editorial brief, unhelpful API key error messages
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Left panel: dark ink (#1A1A1A) bg with decorative blobs, testimonial quote,
avatar, copyright — NOT coral
- Right panel: cream bg, no card/shadow, form directly on page
- editorial-tag (red uppercase label) + Fraunces heading per page
- Google button: outline style (white bg + border)
- Inputs: full border h-11, white bg, focus:border-ink, no border-radius
- Submit CTA: black full-width h-12 → hover accent
- Login/Register as separate form components (not tab toggle)
- Responsive: left panel hidden on mobile
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Redesign Settings: Testi, Immagini, Video, Voiceover — sezioni separate
- Ogni sezione ha dropdown provider + API key + campo opzionale modello
- Opzione "Personalizzato" con campo Base URL libero per qualsiasi servizio
- LLM: aggiunto OpenRouter + provider custom OpenAI-compatible
- Backend: OpenAICompatibleProvider unifica OpenAI/OpenRouter/custom
- Router content: passa llm_base_url a get_llm_provider
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>