fix(pitch): showcase sidebar shows only filtered slides + AI presenter via FAB
Build pitch-deck / build-push-deploy (push) Successful in 1m22s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 31s
CI / test-python-voice (push) Successful in 30s
CI / test-bqas (push) Successful in 31s
Build pitch-deck / build-push-deploy (push) Successful in 1m22s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 31s
CI / test-python-voice (push) Successful in 30s
CI / test-bqas (push) Successful in 31s
NavigationFAB and SlideOverview now accept slideNames prop and render only the active slide list (filtered for showcase mode). Adds AI presenter start button to the FAB footer so it's accessible even when intro-presenter slide is hidden. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,8 @@ interface NavigationFABProps {
|
||||
onGoToSlide: (index: number) => void
|
||||
lang: Language
|
||||
onToggleLanguage: () => void
|
||||
slideNames?: string[]
|
||||
onPresenterStart?: () => void
|
||||
}
|
||||
|
||||
export default function NavigationFAB({
|
||||
@@ -22,6 +24,8 @@ export default function NavigationFAB({
|
||||
onGoToSlide,
|
||||
lang,
|
||||
onToggleLanguage,
|
||||
slideNames: slideNamesProp,
|
||||
onPresenterStart,
|
||||
}: NavigationFABProps) {
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
const [isFullscreen, setIsFullscreen] = useState(false)
|
||||
@@ -35,6 +39,7 @@ export default function NavigationFAB({
|
||||
})
|
||||
}, [])
|
||||
const i = t(lang)
|
||||
const activeSlideNames = slideNamesProp ?? i.slideNames
|
||||
|
||||
const toggleFullscreen = useCallback(() => {
|
||||
if (!document.fullscreenElement) {
|
||||
@@ -89,7 +94,7 @@ export default function NavigationFAB({
|
||||
|
||||
{/* Slide List */}
|
||||
<div className="overflow-y-auto max-h-[55vh] py-2">
|
||||
{i.slideNames.map((name, idx) => {
|
||||
{activeSlideNames.map((name, idx) => {
|
||||
const isActive = idx === currentIndex
|
||||
const isVisited = visitedSlides.has(idx)
|
||||
const isAI = idx === totalSlides - 1
|
||||
@@ -164,6 +169,18 @@ export default function NavigationFAB({
|
||||
</div>
|
||||
</button>
|
||||
|
||||
{/* AI Presenter */}
|
||||
{onPresenterStart && (
|
||||
<button
|
||||
onClick={() => { onPresenterStart(); setIsOpen(false) }}
|
||||
className="w-full flex items-center justify-between px-3 py-2 rounded-lg
|
||||
bg-indigo-500/10 hover:bg-indigo-500/20 transition-colors text-sm"
|
||||
>
|
||||
<span className="text-indigo-300">{lang === 'de' ? 'KI-Präsentation starten' : 'Start AI Presenter'}</span>
|
||||
<Bot className="w-4 h-4 text-indigo-400" />
|
||||
</button>
|
||||
)}
|
||||
|
||||
{/* Fullscreen */}
|
||||
<button
|
||||
onClick={toggleFullscreen}
|
||||
|
||||
@@ -9,6 +9,7 @@ import { usePitchData } from '@/lib/hooks/usePitchData'
|
||||
import { usePresenterMode } from '@/lib/hooks/usePresenterMode'
|
||||
import { useAuditTracker } from '@/lib/hooks/useAuditTracker'
|
||||
import { Language, PitchData } from '@/lib/types'
|
||||
import { t } from '@/lib/i18n'
|
||||
import { Investor } from '@/lib/hooks/useAuth'
|
||||
|
||||
import Link from 'next/link'
|
||||
@@ -85,6 +86,13 @@ export default function PitchDeck({ lang, onToggleLanguage, investor, onLogout,
|
||||
|
||||
const nav = useSlideNavigation(activeSlideOrder)
|
||||
|
||||
// Map active slide IDs → localized names for sidebar/overview
|
||||
const i18n = t(lang)
|
||||
const activeSlideNames = activeSlideOrder.map(id => {
|
||||
const idx = SLIDE_ORDER.indexOf(id)
|
||||
return idx >= 0 ? i18n.slideNames[idx] : id
|
||||
})
|
||||
|
||||
// Skip cap-table slide for Wandeldarlehen versions
|
||||
useEffect(() => {
|
||||
if (nav.currentSlide === 'cap-table' && isWandeldarlehen) {
|
||||
@@ -284,6 +292,8 @@ export default function PitchDeck({ lang, onToggleLanguage, investor, onLogout,
|
||||
onGoToSlide={nav.goToSlide}
|
||||
lang={lang}
|
||||
onToggleLanguage={onToggleLanguage}
|
||||
slideNames={activeSlideNames}
|
||||
onPresenterStart={isShowcase ? presenter.start : undefined}
|
||||
/>
|
||||
|
||||
{/* Presenter UI */}
|
||||
@@ -309,6 +319,7 @@ export default function PitchDeck({ lang, onToggleLanguage, investor, onLogout,
|
||||
onGoToSlide={nav.goToSlide}
|
||||
onClose={() => nav.setShowOverview(false)}
|
||||
lang={lang}
|
||||
slideNames={activeSlideNames}
|
||||
/>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
@@ -9,10 +9,12 @@ interface SlideOverviewProps {
|
||||
onGoToSlide: (index: number) => void
|
||||
onClose: () => void
|
||||
lang: Language
|
||||
slideNames?: string[]
|
||||
}
|
||||
|
||||
export default function SlideOverview({ currentIndex, onGoToSlide, onClose, lang }: SlideOverviewProps) {
|
||||
export default function SlideOverview({ currentIndex, onGoToSlide, onClose, lang, slideNames: slideNamesProp }: SlideOverviewProps) {
|
||||
const i = t(lang)
|
||||
const activeSlideNames = slideNamesProp ?? i.slideNames
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
@@ -28,7 +30,7 @@ export default function SlideOverview({ currentIndex, onGoToSlide, onClose, lang
|
||||
className="grid grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-3 max-w-5xl w-full"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{i.slideNames.map((name, idx) => (
|
||||
{activeSlideNames.map((name, idx) => (
|
||||
<motion.button
|
||||
key={idx}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
|
||||
Reference in New Issue
Block a user