feat(app): Prompt tab shows both query and response in brief format

The Prompt tab now renders the full AI response using magazine extraction
(extractMagazineSections) to create nicely formatted tiles. The user's
query appears as the hero headline, and the response is broken into
styled sections — same as the Brief tab but always available.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-04 18:13:37 +00:00
co-authored by Claude Opus 4.6
parent 2963bca7fe
commit f0d4ae5acc
3 changed files with 20 additions and 2 deletions
@@ -74,7 +74,7 @@
/>
<MagazineGrid
v-else-if="activeTab === 'prompt'"
:sections="[{ title: panelQuery || 'Your Prompt', content: panelQuery }]"
:sections="promptSections"
:hero-image-url="null"
title="Prompt"
:query="panelQuery"
@@ -83,10 +83,12 @@
</template>
<script setup lang="ts">
import { computed } from 'vue'
import type { Film, Song, Podcast, Book, TVSeries, ImageItem, Place } from '@aiui/core/types/content'
import type { WebSearchResult } from '@aiui/core/types/message'
import type { ContentTab, MagazineSection } from '@/composables/useContentPanel'
import { useContentPanel } from '@/composables/useContentPanel'
import { extractMagazineSections, stripContentTags } from '@/composables/contentExtraction'
import FilmGrid from './FilmGrid.vue'
import BookGrid from './BookGrid.vue'
import TVSeriesGrid from './TVSeriesGrid.vue'
@@ -100,7 +102,7 @@ import ProjectGrid from './ProjectGrid.vue'
import DesignSystemGrid from './DesignSystemGrid.vue'
import NostrGrid from './NostrGrid.vue'
defineProps<{
const props = defineProps<{
activeTab: ContentTab
isWideDesktop?: boolean
isMobile?: boolean
@@ -117,8 +119,19 @@ defineProps<{
panelMagazineHeroImage: string | null
panelTitle: string
panelQuery: string
panelResponseText?: string
}>()
const promptSections = computed<MagazineSection[]>(() => {
const text = props.panelResponseText ?? ''
if (!text) return [{ title: props.panelQuery || 'Prompt', content: '' }]
// Use magazine extraction to format the response beautifully
const sections = extractMagazineSections(text)
if (sections.length > 0) return sections
// Fallback: single section with cleaned response
return [{ title: props.panelQuery || 'Response', content: stripContentTags(text) }]
})
const {
openFilmDetail,
openBookDetail,
@@ -53,6 +53,7 @@ const selectedMagazineSection = ref<MagazineSection | null>(null)
const magazineSectionIndex = ref(0)
const panelTitle = ref('Recommended Films')
const panelQuery = ref('')
const panelResponseText = ref('')
const contentType = ref<'film' | 'song' | 'podcast'>('film')
const activeTab = ref<ContentTab>('film')
const availableTabs = ref<ContentTab[]>([])
@@ -74,6 +75,7 @@ export interface DesignSystemItem {
export function useContentPanel() {
function updatePanelFromText(text: string, userQuery = '', webResults: WebSearchResult[] = []) {
panelQuery.value = userQuery.trim()
panelResponseText.value = text
const songs = extractAllSongs(text, userQuery)
let films = extractAllFilms(text)
const podcasts = extractAllPodcasts(text)
@@ -454,6 +456,7 @@ export function useContentPanel() {
magazineSectionIndex,
panelTitle,
panelQuery,
panelResponseText,
contentType,
activeTab,
availableTabs,
+2
View File
@@ -70,6 +70,7 @@
:panel-magazine-hero-image="panelMagazineHeroImage"
:panel-title="panelTitle"
:panel-query="panelQuery"
:panel-response-text="panelResponseText"
@close="closePanel"
/>
</ErrorBoundary>
@@ -401,6 +402,7 @@ const {
panelMagazineHeroImage,
panelTitle,
panelQuery,
panelResponseText,
contentType,
activeTab,
availableTabs,