diff --git a/docs/TASKS/content/008-multi-channel-preview-editor.md b/docs/TASKS/content/008-multi-channel-preview-editor.md
index 5b07d231..d0c31ac3 100644
--- a/docs/TASKS/content/008-multi-channel-preview-editor.md
+++ b/docs/TASKS/content/008-multi-channel-preview-editor.md
@@ -15,12 +15,12 @@ The editor should use one shared content body for every selected target channel,
- Keep content item editing in `frontend/src/features/content/views/ContentItemDetailView.vue`.
- Replace per-channel caption editing with a shared caption and shared hashtags.
- Let configured workspace channels be selected or unselected as targets.
-- Show selected targets in a vertical rail and render preview cards that look closer to social platform previews.
+- Show target channels as a single vertical tab rail and render preview cards that look closer to social platform previews.
- Convert shared hashtags into chip-style entry with suggestions from already used hashtags.
- Show a workspace hashtag feed so authors can reuse existing tags.
- Keep the editor focused on post text and target channels by removing confusing title, calendar, change summary, and base-caption fields.
- Make target preview tabs compact.
-- Move the create content entry point into the main app menu.
+- Move the create content entry point into the top app menu bar.
- Preserve existing save payloads and backend contracts.
## Validation
@@ -40,5 +40,5 @@ npm run build
- [x] Already used hashtags are available as suggestions.
- [x] The editor shows a workspace hashtag feed with usage counts.
- [x] The editor no longer shows title, calendar, change summary, or base-caption fields.
-- [x] Target channel preview tabs use compact buttons.
-- [x] Create content is available from the main app menu.
+- [x] Target channel tabs use compact icon-only buttons with channel names as accessible labels and tooltips.
+- [x] Create content is available from the top app menu bar.
diff --git a/frontend/src/features/content/views/ContentItemDetailView.vue b/frontend/src/features/content/views/ContentItemDetailView.vue
index 6af76506..d00bc611 100644
--- a/frontend/src/features/content/views/ContentItemDetailView.vue
+++ b/frontend/src/features/content/views/ContentItemDetailView.vue
@@ -283,11 +283,11 @@
}
}
- function toggleChannel(channel) {
+ function selectTargetChannel(channel) {
const existing = form.placements.find(placement => placement.channelId === channel.id);
if (existing) {
- removePlacement(existing.id);
+ activePlacementId.value = existing.id;
return;
}
@@ -298,10 +298,6 @@
return form.placements.some(placement => placement.channelId === channelId);
}
- function setActivePlacement(placement) {
- activePlacementId.value = placement.id;
- }
-
function addMedia(placement) {
placement.mediaItems.push(blankMedia());
}
@@ -1104,7 +1100,7 @@
-
-
-
- {{ placement.channelName || placement.network }}
-
-
-
span {
- @apply px-2 text-xs font-bold uppercase tracking-[0.16em];
+ @apply text-[0.62rem] font-bold uppercase tracking-[0.12em];
color: var(--app-text-muted);
}
.target-channel {
- @apply grid min-h-11 w-full grid-cols-[1rem_1.75rem_minmax(0,1fr)] items-center gap-2 rounded-[0.75rem] border px-2.5 py-1.5 text-left transition;
+ @apply relative grid h-10 w-10 place-items-center rounded-[0.75rem] border p-0 transition;
background: var(--app-control-subtle);
border-color: transparent;
color: var(--app-color-on-surface);
@@ -1864,7 +1843,7 @@
}
.target-check {
- @apply text-lg;
+ @apply absolute -right-1 -top-1 text-base;
color: var(--app-color-on-tertiary);
}
@@ -1884,53 +1863,10 @@
color: var(--app-color-on-primary);
}
- .target-channel span {
- @apply flex min-w-0 flex-col gap-0.5;
- }
-
- .target-channel strong,
- .target-channel small {
- @apply block truncate;
- }
-
- .target-channel strong {
- @apply text-xs font-bold;
- }
-
- .target-channel small {
- @apply text-[0.68rem];
- color: var(--app-text-muted);
- }
-
- .target-channel.active small {
- color: rgba(255, 255, 255, 0.72);
- }
-
.preview-stage {
@apply flex min-w-0 flex-col gap-3;
}
- .selected-preview-tabs {
- @apply flex gap-2 overflow-x-auto pb-1;
- }
-
- .selected-preview-tab {
- @apply inline-flex min-h-8 max-w-36 shrink-0 items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs font-bold transition;
- background: var(--app-color-on-primary);
- border-color: var(--app-border-subtle);
- color: var(--app-color-on-surface);
- }
-
- .selected-preview-tab span {
- @apply truncate;
- }
-
- .selected-preview-tab.active {
- background: var(--app-color-on-surface);
- border-color: var(--app-color-on-surface);
- color: var(--app-color-on-primary);
- }
-
.social-preview-card {
@apply flex min-h-[28rem] flex-col gap-4 rounded-[1.25rem] border p-4 shadow-sm;
background: var(--app-color-on-primary);
diff --git a/frontend/src/layouts/main/AppBar.vue b/frontend/src/layouts/main/AppBar.vue
index 30f727bd..b148ef64 100644
--- a/frontend/src/layouts/main/AppBar.vue
+++ b/frontend/src/layouts/main/AppBar.vue
@@ -97,6 +97,17 @@
}
switch (route.name) {
+ case 'workspace-dashboard':
+ case 'content-items':
+ case 'content-item-detail':
+ return authStore.isManager || authStore.isProvider
+ ? [{
+ key: 'create-content',
+ label: t('contentItems.newItem'),
+ icon: mdiPlus,
+ route: { name: 'content-item-create' },
+ }]
+ : [];
case 'campaigns':
return [{
key: 'create-campaign',
diff --git a/frontend/src/layouts/main/AppSidebar.vue b/frontend/src/layouts/main/AppSidebar.vue
index 47c68d9f..f977b602 100644
--- a/frontend/src/layouts/main/AppSidebar.vue
+++ b/frontend/src/layouts/main/AppSidebar.vue
@@ -57,7 +57,6 @@
const primaryLinks = [
{ to: '/app/dashboard', labelKey: 'nav.overview', icon: mdiHomeOutline },
- { to: { name: 'content-item-create' }, key: 'create-content', labelKey: 'contentItems.newItem', icon: mdiPlus },
{ to: '/app/media-library', labelKey: 'nav.mediaLibrary', icon: mdiImageMultipleOutline },
{ to: '/app/developer/release-notes', labelKey: 'nav.releaseNotes', icon: mdiSourceCommit, roles: ['developer'], badge: 'commits' },
];