- Add conditional "Dashboard" link in navbar that shows when a user is logged in - Tests verify the link is hidden for unauthenticated users and visible when authenticated - Investigation reports for Q1 (drafts/scheduled), Q2 (RSS), Q3 (email subs)
153 lines
6.8 KiB
Markdown
153 lines
6.8 KiB
Markdown
# Question 1: "Is there a way to see all drafts and scheduled posts in a list?"
|
|
|
|
## Answer Summary
|
|
|
|
Yes — an editor dashboard exists at `/editor/dashboard` showing all drafts and scheduled posts, but it is **not linked from the navigation**. Only users who know the URL can access it.
|
|
|
|
Public routes (index, homepage, tag pages) never show drafts/scheduled in production. However, authenticated users can view individual draft/scheduled posts **by direct URL** if they know the slug — the show template detects visibility and shows a status banner.
|
|
|
|
---
|
|
|
|
## 1. Existing Views/Routes for Drafts & Scheduled Posts
|
|
|
|
### Editor Dashboard (LiveView) — `/editor/dashboard`
|
|
|
|
- **File:** `app/lib/firehose_web/live/editor_dashboard_live.ex`
|
|
- **Route:** `live "/editor/dashboard", EditorDashboardLive` (router.ex line 87)
|
|
- **Auth:** Requires authenticated user (`:require_authenticated_user` pipe, line 84)
|
|
- **Data source:** `Blogex.Registry.all_posts_unfiltered()` — returns ALL posts regardless of published/date
|
|
- **Features:**
|
|
- Two tabs: Drafts (published=false) and Scheduled (future date)
|
|
- Count badges per tab
|
|
- Shows title, author, date, status badge, and days-until-live for scheduled posts
|
|
- Links each post to its public URL
|
|
|
|
### BlogController.show — individual draft/scheduled post viewing
|
|
|
|
- **File:** `app/lib/firehose_web/controllers/blog_controller.ex`
|
|
- **Route:** `GET /blog/:blog_id/:slug` (router.ex line 38)
|
|
- **Auth:** No auth middleware — but show template only shows status banners when authenticated
|
|
- **Data source:** `blog.get_post!()` (line 22) uses `unfiltered_posts()` — returns ANY post by slug, including drafts/scheduled
|
|
- **Show template** (`app/lib/firehose_web/controllers/blog_html/show.html.heex`, lines 6-22):
|
|
- Shows a draft banner (amber) only when `@authenticated` and visibility is `:draft`
|
|
- Shows a scheduled banner (blue) only when `@authenticated` and visibility is `:scheduled`
|
|
|
|
### BlogController.index / tag — do NOT show drafts/scheduled
|
|
|
|
- Uses `blog.paginate()` / `blog.posts_by_tag()` which call `all_posts()` — filtered in production
|
|
- See section 3 for details
|
|
|
|
---
|
|
|
|
## 2. Is the Editor Dashboard linked from the main navigation?
|
|
|
|
**No.** The navbar in `app/lib/firehose_web/components/layouts/app.html.heex` (lines 1-23) contains:
|
|
|
|
| Link | Target |
|
|
|------|--------|
|
|
| Blog | `/blog/engineering` |
|
|
| Releases | `/blog/releases` |
|
|
| QWAN | `https://qwan.eu` (external) |
|
|
| Contact | `/contact` |
|
|
| Theme toggle | inline JS |
|
|
|
|
There are **no user/authentication-related links at all** — no login, logout, settings, or dashboard link. The layout does not reference `@current_scope` or any authenticated-user assigns.
|
|
|
|
---
|
|
|
|
## 3. Do any public routes show draft or scheduled posts?
|
|
|
|
| Route | Uses | Shows drafts/scheduled? |
|
|
|-------|------|------------------------|
|
|
| `GET /` (homepage) | `recent_posts(3)` → `all_posts()` | ❌ No (filtered) |
|
|
| `GET /blog/:blog_id` (index) | `paginate()` → `all_posts()` | ❌ No (filtered) |
|
|
| `GET /blog/:blog_id/tag/:tag` | `posts_by_tag()` → `all_posts()` | ❌ No (filtered) |
|
|
| `GET /blog/:blog_id/:slug` (show) | `get_post!()` → `unfiltered_posts()` | ✅ Yes — any authenticated user can view via direct URL, with status banner |
|
|
|
|
### Filtering logic (in `Blogex.Blog`, `app/lib/firehose/blog/blog.ex` lines 85-90):
|
|
|
|
```elixir
|
|
def all_posts do
|
|
today = Date.utc_today()
|
|
if Blogex.show_drafts?() do
|
|
Enum.filter(@posts, &(not Date.after?(&1.date, today)))
|
|
else
|
|
Enum.filter(@posts, &(&1.published and not Date.after?(&1.date, today)))
|
|
end
|
|
end
|
|
```
|
|
|
|
- **Dev mode** (`config/config.exs` line 78): `show_drafts: true` — includes drafts (published=false) but excludes future-dated (scheduled)
|
|
- **Prod mode** (`config/prod.exs` line 17): `show_drafts: false` — only live posts visible
|
|
|
|
**Important gap:** `all_posts()` in dev includes drafts but NOT scheduled. The editor dashboard (`all_posts_unfiltered()`) handles both.
|
|
|
|
### Show template control flow (show.html.heex lines 4-22):
|
|
|
|
```heex
|
|
<%= if @authenticated and @visibility == :draft do %>
|
|
<div>Draft — not published</div>
|
|
<% end %>
|
|
|
|
<%= if @authenticated and @visibility == :scheduled do %>
|
|
<div>This post is scheduled for ...</div>
|
|
<% end %>
|
|
```
|
|
|
|
The `@authenticated` flag comes from `conn.assigns[:current_scope]` (BlogController line 33):
|
|
```elixir
|
|
authenticated: !!(conn.assigns[:current_scope] && conn.assigns.current_scope.user)
|
|
```
|
|
|
|
---
|
|
|
|
## 4. What would need to change to add a link to the editor dashboard in the main nav?
|
|
|
|
### Single-file change: `app/lib/firehose_web/components/layouts/app.html.heex`
|
|
|
|
The app layout receives `@current_scope` from the `fetch_current_scope_for_user` plug in the browser pipeline (router.ex line 16). Currently it doesn't use it.
|
|
|
|
**Required addition:** A conditional link inside the `<ul class="flex flex-row ...">` that shows only when `@current_scope` has a user:
|
|
|
|
```heex
|
|
<%= if @current_scope && @current_scope.user do %>
|
|
<li>
|
|
<a href="/editor/dashboard" class="btn btn-ghost btn-sm">Dashboard</a>
|
|
</li>
|
|
<% end %>
|
|
```
|
|
|
|
No router changes needed — the route and LiveView already exist with proper authentication guards.
|
|
|
|
**Optionally**, also add login/logout links for unauthenticated users, so they know how to reach the dashboard.
|
|
|
|
---
|
|
|
|
## 5. What would be the simplest way to make drafts/scheduled visible to editors?
|
|
|
|
### Recommendation: Link the existing dashboard in the nav
|
|
|
|
The EditorDashboardLive at `/editor/dashboard` is fully functional — it shows all drafts and scheduled posts with proper sorting and status badges. The **only** missing piece is discoverability.
|
|
|
|
**Simplest change:**
|
|
1. Add a conditional "Dashboard" link to `app.html.heex` (as described in #4 above) — **~3 lines of code**
|
|
2. Optionally add login/logout links so users can authenticate
|
|
|
|
**Why this is sufficient:**
|
|
- The dashboard is already built and tested
|
|
- It respects authentication (only shows for logged-in users)
|
|
- It covers both drafts **and** scheduled (unlike dev-mode `all_posts()` which only covers drafts)
|
|
- Posts link to their public URLs for preview
|
|
|
|
### Alternative considered: Add drafts/scheduled to public blog index
|
|
|
|
This would be more invasive — it would require:
|
|
- Changing `BlogController.index` to check for authentication and use `unfiltered_posts()` when authenticated
|
|
- Adding an auth plug to the blog routes (currently no auth pipeline there)
|
|
- Modifying templates to show status badges
|
|
|
|
This approach would leak draft titles to unauthenticated users if not done carefully, and is more complex than simply linking the existing dashboard.
|
|
|
|
### Live post preview (already exists)
|
|
|
|
Authenticated users can already view individual draft/scheduled posts by direct URL (`/blog/engineering/some-draft-slug`) with a status banner — `BlogController.show` uses `get_post!()` which returns unfiltered posts. The show template checks `@authenticated` to display the draft/scheduled banner. |