diff --git a/src/app/(dashboard)/dashboard/playground/PlaygroundStudio.tsx b/src/app/(dashboard)/dashboard/playground/PlaygroundStudio.tsx
index 150e4632a4..5796fc90fb 100644
--- a/src/app/(dashboard)/dashboard/playground/PlaygroundStudio.tsx
+++ b/src/app/(dashboard)/dashboard/playground/PlaygroundStudio.tsx
@@ -13,6 +13,8 @@ import type { StreamMetrics } from "@/shared/schemas/playground";
// Lazy-load tabs to reduce initial bundle size
const ChatTab = dynamic(() => import("./components/tabs/ChatTab"), { ssr: false });
const ApiTab = dynamic(() => import("./components/tabs/ApiTab"), { ssr: false });
+const CompareTab = dynamic(() => import("./components/tabs/CompareTab"), { ssr: false });
+const BuildTab = dynamic(() => import("./components/tabs/BuildTab"), { ssr: false });
const INITIAL_METRICS: StreamMetrics = {
ttftMs: null,
@@ -74,6 +76,13 @@ export function PlaygroundStudio() {
activeTab={effectiveTab}
onTabChange={handleTabChange}
metrics={metrics}
+ exportState={{
+ endpoint: configState.endpoint,
+ baseUrl: configState.baseUrl,
+ model: configState.model,
+ systemPrompt: configState.systemPrompt,
+ params: configState.params,
+ }}
/>
{/* Main content area: tab content + config pane */}
@@ -84,27 +93,13 @@ export function PlaygroundStudio() {
)}
{effectiveTab === "compare" && (
-
-
-
- compare
-
-
Compare tab — F7 implementation pending
-
-
+
)}
{effectiveTab === "api" && (
)}
{effectiveTab === "build" && (
-
-
-
- build
-
-
Build tab — F7 implementation pending
-
-
+
)}
diff --git a/src/app/(dashboard)/dashboard/playground/components/StudioConfigPane.tsx b/src/app/(dashboard)/dashboard/playground/components/StudioConfigPane.tsx
index a4c6cc5ec7..f2e76bf95b 100644
--- a/src/app/(dashboard)/dashboard/playground/components/StudioConfigPane.tsx
+++ b/src/app/(dashboard)/dashboard/playground/components/StudioConfigPane.tsx
@@ -6,6 +6,8 @@ import { useState } from "react";
import ParamSliders, { type PlaygroundParams } from "./ParamSliders";
import type { PlaygroundEndpoint } from "@/lib/playground/codeExport";
import { endpointToPath } from "@/lib/playground/codeExport";
+import PresetPicker from "./PresetPicker";
+import ImprovePromptButton from "./ImprovePromptButton";
export interface ConfigState {
endpoint: PlaygroundEndpoint;
@@ -82,8 +84,8 @@ export default function StudioConfigPane({ configState, setConfigState }: Studio
- {/* SLOT_PRESETS: F7 substituirá com PresetPicker */}
- {/* SLOT_PRESETS */}
+ {/* PresetPicker — injected by F7 */}
+
{/* Endpoint */}
@@ -129,8 +131,8 @@ export default function StudioConfigPane({ configState, setConfigState }: Studio
rows={4}
className="w-full text-xs bg-surface border border-border rounded px-2 py-1.5 focus:outline-none focus:ring-1 focus:ring-primary text-text-main resize-y"
/>
- {/* SLOT_IMPROVE: F7 substituirá com ImprovePromptButton */}
- {/* SLOT_IMPROVE */}
+ {/* ImprovePromptButton — injected by F7 */}
+
{/* Param sliders */}
diff --git a/src/app/(dashboard)/dashboard/playground/components/StudioTopBar.tsx b/src/app/(dashboard)/dashboard/playground/components/StudioTopBar.tsx
index 3fcaade678..a477d419f7 100644
--- a/src/app/(dashboard)/dashboard/playground/components/StudioTopBar.tsx
+++ b/src/app/(dashboard)/dashboard/playground/components/StudioTopBar.tsx
@@ -4,7 +4,9 @@
import { useState } from "react";
import TokenCostCounter from "./TokenCostCounter";
+import ExportCodeModal from "./ExportCodeModal";
import type { StreamMetrics } from "@/shared/schemas/playground";
+import type { PlaygroundState } from "@/lib/playground/codeExport";
export type StudioTab = "chat" | "compare" | "api" | "build";
@@ -12,6 +14,8 @@ interface StudioTopBarProps {
activeTab: StudioTab;
onTabChange: (tab: StudioTab) => void;
metrics: StreamMetrics;
+ /** Optional playground state for the Export code modal. If omitted, a minimal state is used. */
+ exportState?: PlaygroundState;
}
interface TabConfig {
@@ -29,9 +33,9 @@ const TABS: TabConfig[] = [
/**
* Top bar with tab switcher, token/cost counter, and export code button.
- * Export code modal is a placeholder in F6; F7 replaces it with ExportCodeModal.
+ * Export code modal uses ExportCodeModal (F7) when exportState is provided.
*/
-export default function StudioTopBar({ activeTab, onTabChange, metrics }: StudioTopBarProps) {
+export default function StudioTopBar({ activeTab, onTabChange, metrics, exportState }: StudioTopBarProps) {
const [exportOpen, setExportOpen] = useState(false);
return (
@@ -77,8 +81,11 @@ export default function StudioTopBar({ activeTab, onTabChange, metrics }: Studio
- {/* Export code placeholder modal — F7 replaces with ExportCodeModal */}
- {exportOpen && (
+ {/* Export code modal — uses ExportCodeModal (F7) */}
+ {exportOpen && exportState != null && (
+ setExportOpen(false)} />
+ )}
+ {exportOpen && exportState == null && (
setExportOpen(false)}
@@ -98,7 +105,7 @@ export default function StudioTopBar({ activeTab, onTabChange, metrics }: Studio
- Export code modal — F7 implementation pending.
+ No playground state available to export.