mirror of
https://github.com/f/awesome-chatgpt-prompts.git
synced 2025-06-23 07:55:08 +00:00
Compare commits
5 Commits
c60d434a43
...
9a5acf16fb
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9a5acf16fb | ||
![]() |
fd8782ae62 | ||
![]() |
e3b9457a46 | ||
![]() |
fb3607e51f | ||
![]() |
a9efb68d97 |
@ -26,6 +26,46 @@
|
|||||||
<link rel="stylesheet" href="{{ '/embed-preview-style.css' | relative_url }}">
|
<link rel="stylesheet" href="{{ '/embed-preview-style.css' | relative_url }}">
|
||||||
<link rel="icon" type="image/x-icon" href="{{ '/favicon.ico' | relative_url }}">
|
<link rel="icon" type="image/x-icon" href="{{ '/favicon.ico' | relative_url }}">
|
||||||
<meta name="description" content="AI prompt viewer">
|
<meta name="description" content="AI prompt viewer">
|
||||||
|
<style>
|
||||||
|
@keyframes flash {
|
||||||
|
0%, 100% { opacity: 1; }
|
||||||
|
50% { opacity: 0.4; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.flash-animation {
|
||||||
|
animation: flash 1.5s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideUp {
|
||||||
|
from {
|
||||||
|
transform: translateY(100%);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateY(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideDown {
|
||||||
|
from {
|
||||||
|
transform: translateY(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateY(100%);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-enter {
|
||||||
|
animation: slideUp 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-exit {
|
||||||
|
animation: slideDown 0.3s ease-out;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-dynamic-background text-dynamic-foreground overflow-hidden">
|
<body class="bg-dynamic-background text-dynamic-foreground overflow-hidden">
|
||||||
<!-- Viewer Mode -->
|
<!-- Viewer Mode -->
|
||||||
@ -39,9 +79,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Main Content -->
|
<!-- Main Content -->
|
||||||
<div class="flex-1 flex flex-col p-2 sm:p-4 min-h-0">
|
<div class="flex-1 flex flex-col p-2 sm:p-4 h-full overflow-hidden">
|
||||||
<!-- Top Bar with Context Pills and Edit Button -->
|
<!-- Top Bar with Context Pills and Edit Button -->
|
||||||
<div class="flex justify-between items-start gap-2 mb-1 sm:mb-2 max-w-full flex-shrink-0">
|
<div class="flex justify-between items-start gap-2 mb-1 sm:mb-2 flex-shrink-0">
|
||||||
<!-- Context Pills -->
|
<!-- Context Pills -->
|
||||||
<div id="context-pills" class="flex flex-wrap gap-1.5 empty:hidden flex-1 min-w-0 pr-2"></div>
|
<div id="context-pills" class="flex flex-wrap gap-1.5 empty:hidden flex-1 min-w-0 pr-2"></div>
|
||||||
|
|
||||||
@ -54,22 +94,98 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Main Prompt Interface - Full Height -->
|
<!-- Main Prompt Interface with Floating Diff - Flex-1 to take remaining space -->
|
||||||
<div class="flex-1 flex flex-col min-h-0">
|
<div class="flex-1 relative min-h-0 overflow-hidden">
|
||||||
<div id="prompt-container" class="flex-1 bg-dynamic-muted border border-dynamic-border rounded-xl p-3 relative focus-within:border-dynamic-primary transition-colors flex flex-col min-h-0">
|
<!-- Floating Diff View (when enabled and viewport is compact) -->
|
||||||
<div id="prompt-text" class="flex-1 text-dynamic-foreground leading-relaxed whitespace-pre-wrap overflow-y-auto custom-scrollbar text-sm sm:text-base"></div>
|
<div id="diff-view" class="hidden absolute top-2 left-2 right-2 z-10 diff-floating">
|
||||||
<div id="prompt-placeholder" class="text-dynamic-muted-foreground italic absolute top-3 left-3 pointer-events-none text-sm sm:text-base">← Enter your prompt on designer...</div>
|
<div class="bg-dynamic-background/95 backdrop-blur-sm border border-dynamic-border shadow-lg rounded-lg p-3">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div class="flex items-center gap-1.5">
|
||||||
|
<svg class="w-3 h-3 text-dynamic-primary flex-shrink-0" viewBox="0 0 20 20" fill="currentColor">
|
||||||
|
<path fill-rule="evenodd" d="M4 2a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V7.414A2 2 0 0017.414 6L14 2.586A2 2 0 0012.586 2H4zm2 4a1 1 0 011-1h4a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7zm-1 5a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1z" clip-rule="evenodd"/>
|
||||||
|
</svg>
|
||||||
|
<span id="diff-filename" class="text-xs font-medium text-dynamic-foreground truncate"></span>
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-1 items-center">
|
||||||
|
<div class="flex rounded-md overflow-hidden">
|
||||||
|
<button id="diff-accept-diff" class="px-2 py-0.5 bg-green-500 hover:bg-green-600 text-white text-[10px] font-medium transition-colors flex items-center gap-0.5">
|
||||||
|
<svg class="w-2.5 h-2.5" viewBox="0 0 20 20" fill="currentColor">
|
||||||
|
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||||||
|
</svg>
|
||||||
|
<span class="hidden sm:inline">Accept</span>
|
||||||
|
</button>
|
||||||
|
<button id="diff-reject-diff" class="px-2 py-0.5 bg-red-500 hover:bg-red-600 text-white text-[10px] font-medium transition-colors flex items-center gap-0.5">
|
||||||
|
<svg class="w-2.5 h-2.5" viewBox="0 0 20 20" fill="currentColor">
|
||||||
|
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
|
||||||
|
</svg>
|
||||||
|
<span class="hidden sm:inline">Reject</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<!-- Collapse/Expand button -->
|
||||||
|
<button id="toggle-diff" class="p-0.5 text-dynamic-muted-foreground hover:text-dynamic-foreground transition-colors" title="Toggle diff view">
|
||||||
|
<svg class="w-3 h-3 transform transition-transform" viewBox="0 0 20 20" fill="currentColor">
|
||||||
|
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="diff-content" class="space-y-1 transition-all duration-300 overflow-hidden">
|
||||||
|
<div id="diff-old-content" class="bg-red-50/70 dark:bg-red-950/20 p-2 rounded text-[10px] font-mono whitespace-pre-wrap text-red-700 dark:text-red-400 overflow-x-auto border border-red-200/50 dark:border-red-900/30 max-h-20 overflow-y-auto custom-scrollbar"></div>
|
||||||
|
<div id="diff-new-content" class="bg-green-50/70 dark:bg-green-950/20 p-2 rounded text-[10px] font-mono whitespace-pre-wrap text-green-700 dark:text-green-400 overflow-x-auto border border-green-200/50 dark:border-green-900/30 max-h-20 overflow-y-auto custom-scrollbar"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Container for inline diff and prompt -->
|
||||||
|
<div class="h-full flex flex-col">
|
||||||
|
<!-- Inline Diff View (when enabled and viewport has space) -->
|
||||||
|
<div id="diff-view-inline" class="hidden mb-2 flex-shrink-0">
|
||||||
|
<div class="bg-dynamic-muted border border-dynamic-border rounded-lg p-2">
|
||||||
|
<div class="flex items-center justify-between mb-1.5">
|
||||||
|
<div class="flex items-center gap-1.5">
|
||||||
|
<svg class="w-3 h-3 text-dynamic-primary flex-shrink-0" viewBox="0 0 20 20" fill="currentColor">
|
||||||
|
<path fill-rule="evenodd" d="M4 2a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V7.414A2 2 0 0017.414 6L14 2.586A2 2 0 0012.586 2H4zm2 4a1 1 0 011-1h4a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7zm-1 5a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1z" clip-rule="evenodd"/>
|
||||||
|
</svg>
|
||||||
|
<span id="inline-diff-filename" class="text-xs font-medium text-dynamic-foreground truncate"></span>
|
||||||
|
</div>
|
||||||
|
<div class="flex rounded-md overflow-hidden">
|
||||||
|
<button id="inline-accept-diff" class="px-2 py-0.5 bg-green-500 hover:bg-green-600 text-white text-[10px] font-medium transition-colors flex items-center gap-0.5">
|
||||||
|
<svg class="w-2.5 h-2.5" viewBox="0 0 20 20" fill="currentColor">
|
||||||
|
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||||||
|
</svg>
|
||||||
|
<span class="hidden sm:inline">Accept</span>
|
||||||
|
</button>
|
||||||
|
<button id="inline-reject-diff" class="px-2 py-0.5 bg-red-500 hover:bg-red-600 text-white text-[10px] font-medium transition-colors flex items-center gap-0.5">
|
||||||
|
<svg class="w-2.5 h-2.5" viewBox="0 0 20 20" fill="currentColor">
|
||||||
|
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
|
||||||
|
</svg>
|
||||||
|
<span class="hidden sm:inline">Reject</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-0.5">
|
||||||
|
<div id="inline-old-content" class="bg-red-50/70 dark:bg-red-950/20 p-1 rounded text-[10px] font-mono whitespace-pre-wrap text-red-700 dark:text-red-400 overflow-x-auto border border-red-200/50 dark:border-red-900/30 max-h-20 overflow-y-auto custom-scrollbar"></div>
|
||||||
|
<div id="inline-new-content" class="bg-green-50/70 dark:bg-green-950/20 p-1 rounded text-[10px] font-mono whitespace-pre-wrap text-green-700 dark:text-green-400 overflow-x-auto border border-green-200/50 dark:border-green-900/30 max-h-20 overflow-y-auto custom-scrollbar"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Prompt Container - Full height of parent -->
|
||||||
|
<div id="prompt-container" class="flex-1 bg-dynamic-muted border border-dynamic-border rounded-xl p-3 relative focus-within:border-dynamic-primary transition-colors flex flex-col min-h-0">
|
||||||
|
<div id="prompt-text" class="flex-1 text-dynamic-foreground leading-relaxed whitespace-pre-wrap overflow-y-auto custom-scrollbar text-sm sm:text-base duration-300"></div>
|
||||||
|
<div id="prompt-placeholder" class="text-dynamic-muted-foreground italic absolute top-3 left-3 pointer-events-none text-sm sm:text-base">← Enter your prompt on designer...</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Bottom Bar -->
|
<!-- Bottom Bar - Always visible with reduced height -->
|
||||||
<div class="flex justify-between items-center gap-2 mt-1 sm:mt-2 flex-shrink-0">
|
<div class="flex justify-between items-center gap-2 mt-1 pt-1 flex-shrink-0">
|
||||||
<!-- Settings Pills -->
|
<!-- Settings Pills - Smaller -->
|
||||||
<div id="settings-pills" class="flex gap-1 sm:gap-2 flex-wrap flex-1 min-w-0"></div>
|
<div id="settings-pills" class="flex gap-1 flex-wrap flex-1 min-w-0"></div>
|
||||||
|
|
||||||
<!-- Send Button (circular with arrow up) -->
|
<!-- Send Button - Smaller -->
|
||||||
<button id="copy-button" class="w-8 h-8 sm:w-10 sm:h-10 bg-dynamic-primary text-white rounded-full flex items-center justify-center hover:opacity-90 transition-opacity focus-ring flex-shrink-0 shadow-lg touch-target" title="Send prompt">
|
<button id="copy-button" class="w-7 h-7 sm:w-8 sm:h-8 bg-dynamic-primary text-white rounded-full flex items-center justify-center hover:opacity-90 transition-opacity flex-shrink-0 shadow-md" title="Send prompt">
|
||||||
<svg width="16" height="16" class="sm:w-5 sm:h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
|
<svg width="14" height="14" class="sm:w-4 sm:h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
|
||||||
<path d="M12 19V5M5 12l7-7 7 7"/>
|
<path d="M12 19V5M5 12l7-7 7 7"/>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
@ -27,8 +27,30 @@
|
|||||||
<link rel="stylesheet" href="{{ '/embed-style.css' | relative_url }}">
|
<link rel="stylesheet" href="{{ '/embed-style.css' | relative_url }}">
|
||||||
<link rel="icon" type="image/x-icon" href="{{ '/favicon.ico' | relative_url }}">
|
<link rel="icon" type="image/x-icon" href="{{ '/favicon.ico' | relative_url }}">
|
||||||
<meta name="description" content="Design and customize embeddable AI prompts">
|
<meta name="description" content="Design and customize embeddable AI prompts">
|
||||||
|
<style>
|
||||||
|
.checkerboard-bg {
|
||||||
|
background-image:
|
||||||
|
linear-gradient(45deg, rgba(0,0,0,0.06) 25%, transparent 25%),
|
||||||
|
linear-gradient(-45deg, rgba(0,0,0,0.06) 25%, transparent 25%),
|
||||||
|
linear-gradient(45deg, transparent 75%, rgba(0,0,0,0.06) 75%),
|
||||||
|
linear-gradient(-45deg, transparent 75%, rgba(0,0,0,0.06) 75%);
|
||||||
|
background-size: 20px 20px;
|
||||||
|
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .checkerboard-bg {
|
||||||
|
background-color: #1e1e1e;
|
||||||
|
background-image:
|
||||||
|
linear-gradient(45deg, #353535 25%, transparent 25%),
|
||||||
|
linear-gradient(-45deg, #353535 25%, transparent 25%),
|
||||||
|
linear-gradient(45deg, transparent 75%, #353535 75%),
|
||||||
|
linear-gradient(-45deg, transparent 75%, #353535 75%);
|
||||||
|
background-size: 16px 16px;
|
||||||
|
background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-dynamic-background text-dynamic-foreground overflow-hidden">
|
<body class="bg-dynamic-background text-dynamic-foreground overflow-hidden checkerboard-bg">
|
||||||
<!-- Site Header -->
|
<!-- Site Header -->
|
||||||
<header class="site-header">
|
<header class="site-header">
|
||||||
<div class="header-left">
|
<div class="header-left">
|
||||||
@ -37,6 +59,13 @@
|
|||||||
<p class="site-slogan sm:hidden">Design and share AI prompts</p>
|
<p class="site-slogan sm:hidden">Design and share AI prompts</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
|
<a href="https://blog.fka.dev/blog/2025-06-18-building-a-react-hook-with-ai-a-step-by-step-guide-using-vibe-an-example-post-that-uses-prompts-chat-embed/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="flex items-center text-xs text-dynamic-muted-foreground hover:text-dynamic-foreground transition-colors mr-3 touch-target hidden sm:inline-flex"
|
||||||
|
title="View example blog post using prompts.chat embed">
|
||||||
|
View example blog post
|
||||||
|
</a>
|
||||||
<button class="dark-mode-toggle touch-target" onclick="toggleDarkMode()" title="Toggle dark mode">
|
<button class="dark-mode-toggle touch-target" onclick="toggleDarkMode()" title="Toggle dark mode">
|
||||||
<svg class="mode-icon sun-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line></svg>
|
<svg class="mode-icon sun-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line></svg>
|
||||||
<svg class="mode-icon moon-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display: none;"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
|
<svg class="mode-icon moon-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display: none;"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
|
||||||
@ -49,127 +78,144 @@
|
|||||||
<!-- Left Panel - Customization -->
|
<!-- Left Panel - Customization -->
|
||||||
<div class="designer-panel w-full lg:w-80 flex flex-col h-auto lg:h-full overflow-hidden order-2 lg:order-1 flex-shrink-0">
|
<div class="designer-panel w-full lg:w-80 flex flex-col h-auto lg:h-full overflow-hidden order-2 lg:order-1 flex-shrink-0">
|
||||||
<div class="flex-1 overflow-y-auto custom-scrollbar">
|
<div class="flex-1 overflow-y-auto custom-scrollbar">
|
||||||
<div class="p-4 lg:p-6 lg:pt-0 space-y-4">
|
<div class="p-3 lg:p-4 space-y-3">
|
||||||
<!-- Context -->
|
|
||||||
<div class="space-y-2">
|
|
||||||
<label class="text-sm font-medium text-dynamic-muted-foreground">Context</label>
|
|
||||||
<input type="text" id="designer-context"
|
|
||||||
class="w-full p-3 lg:p-2 bg-dynamic-background border border-dynamic-border rounded-lg text-sm focus-ring touch-target"
|
|
||||||
placeholder="file.py, @web, @codebase, #image">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Prompt Text -->
|
<!-- CONTENT SECTION -->
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<label class="text-sm font-medium text-dynamic-muted-foreground">Prompt Text</label>
|
<h3 class="text-xs font-semibold text-dynamic-foreground uppercase tracking-wider border-b border-dynamic-border pb-1">Prompt</h3>
|
||||||
<textarea id="designer-prompt"
|
|
||||||
class="w-full p-3 bg-dynamic-background border border-dynamic-border rounded-lg text-sm resize-none focus-ring custom-scrollbar touch-target"
|
|
||||||
rows="8"
|
|
||||||
placeholder="Enter your prompt..."></textarea>
|
|
||||||
<div class="flex gap-3">
|
|
||||||
<button type="button" id="vibe-example" class="text-xs text-dynamic-primary hover:text-opacity-80 transition-opacity touch-target py-1">
|
|
||||||
Vibe coding example →
|
|
||||||
</button>
|
|
||||||
<button type="button" id="chat-example" class="text-xs text-dynamic-primary hover:text-opacity-80 transition-opacity touch-target py-1">
|
|
||||||
Chat example →
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Model & Mode -->
|
<!-- Example Selector -->
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
<div class="space-y-1">
|
||||||
<div class="space-y-2">
|
<label class="text-xs font-medium text-dynamic-muted-foreground">Load Example</label>
|
||||||
<label class="text-sm font-medium text-dynamic-muted-foreground">Model</label>
|
<select id="example-select" class="w-full p-2 bg-dynamic-muted border border-dynamic-border rounded text-xs focus-ring touch-target">
|
||||||
<select id="designer-model" class="w-full p-3 lg:p-2 bg-dynamic-background border border-dynamic-border rounded-lg text-sm focus-ring touch-target">
|
<option value="">Choose an example...</option>
|
||||||
<option value="o3">o3</option>
|
<option value="vibe-coding">Vibe coding (no diff)</option>
|
||||||
<option value="GPT 4.1">GPT 4.1</option>
|
<option value="vibe-coding-diff">Vibe coding with diff</option>
|
||||||
<option value="GPT 4o" selected>GPT 4o</option>
|
<option value="chatgpt">ChatGPT example</option>
|
||||||
<option value="Claude 3.7 Sonnet">Claude 3.7 Sonnet</option>
|
<option value="claude">Claude example</option>
|
||||||
<option value="Claude 4 Sonnet">Claude 4 Sonnet</option>
|
<option value="image-analysis">Image analysis</option>
|
||||||
<option value="Claude 4 Opus">Claude 4 Opus</option>
|
<option value="api-design">API design</option>
|
||||||
<option value="Gemini 2.5 Pro">Gemini 2.5 Pro</option>
|
|
||||||
<option value="DeepSeek R1">DeepSeek R1</option>
|
|
||||||
<option value="custom">[Custom]</option>
|
|
||||||
</select>
|
|
||||||
<input type="text" id="designer-custom-model"
|
|
||||||
class="w-full p-3 lg:p-2 bg-dynamic-background border border-dynamic-border rounded-lg text-sm focus-ring hidden touch-target"
|
|
||||||
placeholder="Enter custom model name">
|
|
||||||
</div>
|
|
||||||
<div class="space-y-2">
|
|
||||||
<label class="text-sm font-medium text-dynamic-muted-foreground">Mode</label>
|
|
||||||
<select id="designer-mode-select" class="w-full p-3 lg:p-2 bg-dynamic-background border border-dynamic-border rounded-lg text-sm focus-ring touch-target">
|
|
||||||
<option value="chat">Chat</option>
|
|
||||||
<option value="agent">Agent</option>
|
|
||||||
<option value="manual">Manual</option>
|
|
||||||
<option value="cloud">Cloud</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Options -->
|
<!-- Context -->
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2 justify-items-start">
|
<div class="space-y-1">
|
||||||
<label class="flex items-center space-x-2 touch-target">
|
<label class="text-xs font-medium text-dynamic-muted-foreground">Context</label>
|
||||||
<input type="checkbox" id="designer-thinking" class="rounded border-dynamic-border w-4 h-4">
|
<input type="text" id="designer-context"
|
||||||
<span class="text-sm text-dynamic-muted-foreground">Thinking</span>
|
class="w-full p-2 bg-dynamic-background border border-dynamic-border rounded text-xs focus-ring touch-target"
|
||||||
</label>
|
placeholder="file.py, @web, @codebase, #image">
|
||||||
<label class="flex items-center space-x-2 touch-target">
|
</div>
|
||||||
<input type="checkbox" id="designer-max" class="rounded border-dynamic-border w-4 h-4">
|
|
||||||
<span class="text-sm text-dynamic-muted-foreground">MAX mode</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Theme Mode Selector -->
|
<!-- Prompt Text -->
|
||||||
<div class="space-y-2">
|
<div class="space-y-1">
|
||||||
<label class="text-sm font-medium text-dynamic-muted-foreground">Theme Mode</label>
|
<label class="text-xs font-medium text-dynamic-muted-foreground">Prompt Text</label>
|
||||||
<div class="grid grid-cols-3 gap-2">
|
<textarea id="designer-prompt"
|
||||||
<button type="button" id="theme-light" class="theme-mode-btn px-3 py-3 lg:py-2 text-xs font-medium rounded-lg border border-dynamic-border bg-dynamic-background hover:bg-dynamic-muted transition-colors text-center touch-target">
|
class="w-full p-2 bg-dynamic-background border border-dynamic-border rounded text-xs resize-none focus-ring custom-scrollbar touch-target"
|
||||||
Light
|
rows="6"
|
||||||
</button>
|
placeholder="Enter your prompt..."></textarea>
|
||||||
<button type="button" id="theme-dark" class="theme-mode-btn px-3 py-3 lg:py-2 text-xs font-medium rounded-lg border border-dynamic-border bg-dynamic-background hover:bg-dynamic-muted transition-colors text-center touch-target">
|
|
||||||
Dark
|
|
||||||
</button>
|
|
||||||
<button type="button" id="theme-auto" class="theme-mode-btn px-3 py-3 lg:py-2 text-xs font-medium rounded-lg border border-dynamic-border bg-dynamic-primary text-white transition-colors text-center touch-target">
|
|
||||||
Auto
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Color Scheme -->
|
<!-- AI SETTINGS SECTION -->
|
||||||
<div class="space-y-3">
|
<div class="space-y-2">
|
||||||
<label class="text-sm font-medium text-dynamic-muted-foreground">Color Scheme</label>
|
<h3 class="text-xs font-semibold text-dynamic-foreground uppercase tracking-wider border-b border-dynamic-border pb-1">AI Settings</h3>
|
||||||
|
|
||||||
|
<!-- Model & Mode Grid -->
|
||||||
|
<div class="grid grid-cols-2 gap-2">
|
||||||
|
<div class="space-y-1">
|
||||||
|
<label class="text-xs font-medium text-dynamic-muted-foreground">Model</label>
|
||||||
|
<select id="designer-model" class="w-full p-2 bg-dynamic-background border border-dynamic-border rounded text-xs focus-ring touch-target">
|
||||||
|
<option value="o3">o3</option>
|
||||||
|
<option value="GPT 4.1">GPT 4.1</option>
|
||||||
|
<option value="GPT 4o" selected>GPT 4o</option>
|
||||||
|
<option value="Claude 3.7 Sonnet">Claude 3.7 Sonnet</option>
|
||||||
|
<option value="Claude 4 Sonnet">Claude 4 Sonnet</option>
|
||||||
|
<option value="Claude 4 Opus">Claude 4 Opus</option>
|
||||||
|
<option value="Gemini 2.5 Pro">Gemini 2.5 Pro</option>
|
||||||
|
<option value="DeepSeek R1">DeepSeek R1</option>
|
||||||
|
<option value="custom">[Custom]</option>
|
||||||
|
</select>
|
||||||
|
<input type="text" id="designer-custom-model"
|
||||||
|
class="w-full p-2 bg-dynamic-background border border-dynamic-border rounded text-xs focus-ring hidden touch-target"
|
||||||
|
placeholder="Custom model">
|
||||||
|
</div>
|
||||||
|
<div class="space-y-1">
|
||||||
|
<label class="text-xs font-medium text-dynamic-muted-foreground">Mode</label>
|
||||||
|
<select id="designer-mode-select" class="w-full p-2 bg-dynamic-background border border-dynamic-border rounded text-xs focus-ring touch-target">
|
||||||
|
<option value="chat">Chat</option>
|
||||||
|
<option value="agent">Agent</option>
|
||||||
|
<option value="manual">Manual</option>
|
||||||
|
<option value="cloud">Cloud</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Options -->
|
||||||
|
<div class="flex gap-4">
|
||||||
|
<label class="flex items-center space-x-1.5 touch-target">
|
||||||
|
<input type="checkbox" id="designer-thinking" class="rounded border-dynamic-border w-3.5 h-3.5">
|
||||||
|
<span class="text-xs text-dynamic-muted-foreground">Thinking</span>
|
||||||
|
</label>
|
||||||
|
<label class="flex items-center space-x-1.5 touch-target">
|
||||||
|
<input type="checkbox" id="designer-max" class="rounded border-dynamic-border w-3.5 h-3.5">
|
||||||
|
<span class="text-xs text-dynamic-muted-foreground">MAX mode</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- APPEARANCE SECTION -->
|
||||||
|
<div class="space-y-2">
|
||||||
|
<h3 class="text-xs font-semibold text-dynamic-foreground uppercase tracking-wider border-b border-dynamic-border pb-1">Appearance</h3>
|
||||||
|
|
||||||
|
<!-- Theme Mode -->
|
||||||
|
<div class="space-y-1">
|
||||||
|
<label class="text-xs font-medium text-dynamic-muted-foreground">Theme</label>
|
||||||
|
<div class="grid grid-cols-3 gap-1">
|
||||||
|
<button type="button" id="theme-light" class="theme-mode-btn px-2 py-1.5 text-xs font-medium rounded border border-dynamic-border bg-dynamic-background hover:bg-dynamic-muted transition-colors text-center touch-target">
|
||||||
|
Light
|
||||||
|
</button>
|
||||||
|
<button type="button" id="theme-dark" class="theme-mode-btn px-2 py-1.5 text-xs font-medium rounded border border-dynamic-border bg-dynamic-background hover:bg-dynamic-muted transition-colors text-center touch-target">
|
||||||
|
Dark
|
||||||
|
</button>
|
||||||
|
<button type="button" id="theme-auto" class="theme-mode-btn px-2 py-1.5 text-xs font-medium rounded border border-dynamic-border bg-dynamic-primary text-white transition-colors text-center touch-target">
|
||||||
|
Auto
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Color Presets -->
|
<!-- Color Presets -->
|
||||||
<div class="space-y-2">
|
<div class="space-y-1">
|
||||||
<label class="text-xs text-dynamic-muted-foreground uppercase tracking-wider">Presets</label>
|
<label class="text-xs font-medium text-dynamic-muted-foreground">Colors</label>
|
||||||
<div class="grid grid-cols-4 gap-2">
|
<div class="grid grid-cols-8 gap-1">
|
||||||
<button type="button" class="color-preset w-full h-10 lg:h-8 rounded-lg border-2 border-transparent hover:border-dynamic-primary transition-colors touch-target"
|
<button type="button" class="color-preset w-full h-6 rounded border border-dynamic-border hover:border-dynamic-primary transition-colors touch-target"
|
||||||
data-light="#6b7280" data-dark="#e5e7eb"
|
data-light="#6b7280" data-dark="#e5e7eb"
|
||||||
style="background: linear-gradient(135deg, #6b7280 50%, #e5e7eb 50%)"
|
style="background: linear-gradient(135deg, #6b7280 50%, #e5e7eb 50%)"
|
||||||
title="Minimal"></button>
|
title="Minimal"></button>
|
||||||
<button type="button" class="color-preset w-full h-10 lg:h-8 rounded-lg border-2 border-transparent hover:border-dynamic-primary transition-colors touch-target"
|
<button type="button" class="color-preset w-full h-6 rounded border border-dynamic-border hover:border-dynamic-primary transition-colors touch-target"
|
||||||
data-light="#1f2937" data-dark="#9ca3af"
|
data-light="#1f2937" data-dark="#9ca3af"
|
||||||
style="background: linear-gradient(135deg, #1f2937 50%, #9ca3af 50%)"
|
style="background: linear-gradient(135deg, #1f2937 50%, #9ca3af 50%)"
|
||||||
title="Dark Gray"></button>
|
title="Dark Gray"></button>
|
||||||
<button type="button" class="color-preset w-full h-10 lg:h-8 rounded-lg border-2 border-transparent hover:border-dynamic-primary transition-colors touch-target"
|
<button type="button" class="color-preset w-full h-6 rounded border border-dynamic-border hover:border-dynamic-primary transition-colors touch-target"
|
||||||
data-light="#64748b" data-dark="#94a3b8"
|
data-light="#64748b" data-dark="#94a3b8"
|
||||||
style="background: linear-gradient(135deg, #64748b 50%, #94a3b8 50%)"
|
style="background: linear-gradient(135deg, #64748b 50%, #94a3b8 50%)"
|
||||||
title="Dimmed"></button>
|
title="Dimmed"></button>
|
||||||
<button type="button" class="color-preset w-full h-10 lg:h-8 rounded-lg border-2 border-transparent hover:border-dynamic-primary transition-colors touch-target"
|
<button type="button" class="color-preset w-full h-6 rounded border border-dynamic-border hover:border-dynamic-primary transition-colors touch-target"
|
||||||
data-light="#3b82f6" data-dark="#60a5fa"
|
data-light="#3b82f6" data-dark="#60a5fa"
|
||||||
style="background: linear-gradient(135deg, #3b82f6 50%, #60a5fa 50%)"
|
style="background: linear-gradient(135deg, #3b82f6 50%, #60a5fa 50%)"
|
||||||
title="Blue"></button>
|
title="Blue"></button>
|
||||||
<button type="button" class="color-preset w-full h-10 lg:h-8 rounded-lg border-2 border-transparent hover:border-dynamic-primary transition-colors touch-target"
|
<button type="button" class="color-preset w-full h-6 rounded border border-dynamic-border hover:border-dynamic-primary transition-colors touch-target"
|
||||||
data-light="#10b981" data-dark="#34d399"
|
data-light="#10b981" data-dark="#34d399"
|
||||||
style="background: linear-gradient(135deg, #10b981 50%, #34d399 50%)"
|
style="background: linear-gradient(135deg, #10b981 50%, #34d399 50%)"
|
||||||
title="Green"></button>
|
title="Green"></button>
|
||||||
<button type="button" class="color-preset w-full h-10 lg:h-8 rounded-lg border-2 border-transparent hover:border-dynamic-primary transition-colors touch-target"
|
<button type="button" class="color-preset w-full h-6 rounded border border-dynamic-border hover:border-dynamic-primary transition-colors touch-target"
|
||||||
data-light="#8b5cf6" data-dark="#a78bfa"
|
data-light="#8b5cf6" data-dark="#a78bfa"
|
||||||
style="background: linear-gradient(135deg, #8b5cf6 50%, #a78bfa 50%)"
|
style="background: linear-gradient(135deg, #8b5cf6 50%, #a78bfa 50%)"
|
||||||
title="Purple"></button>
|
title="Purple"></button>
|
||||||
<button type="button" class="color-preset w-full h-10 lg:h-8 rounded-lg border-2 border-transparent hover:border-dynamic-primary transition-colors touch-target"
|
<button type="button" class="color-preset w-full h-6 rounded border border-dynamic-border hover:border-dynamic-primary transition-colors touch-target"
|
||||||
data-light="#f97316" data-dark="#fb923c"
|
data-light="#f97316" data-dark="#fb923c"
|
||||||
style="background: linear-gradient(135deg, #f97316 50%, #fb923c 50%)"
|
style="background: linear-gradient(135deg, #f97316 50%, #fb923c 50%)"
|
||||||
title="Orange"></button>
|
title="Orange"></button>
|
||||||
<button type="button" class="color-preset w-full h-10 lg:h-8 rounded-lg border-2 border-transparent hover:border-dynamic-primary transition-colors touch-target"
|
<button type="button" class="color-preset w-full h-6 rounded border border-dynamic-border hover:border-dynamic-primary transition-colors touch-target"
|
||||||
data-light="#ec4899" data-dark="#f472b6"
|
data-light="#ec4899" data-dark="#f472b6"
|
||||||
style="background: linear-gradient(135deg, #ec4899 50%, #f472b6 50%)"
|
style="background: linear-gradient(135deg, #ec4899 50%, #f472b6 50%)"
|
||||||
title="Pink"></button>
|
title="Pink"></button>
|
||||||
@ -177,88 +223,115 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Custom Colors -->
|
<!-- Custom Colors -->
|
||||||
<div class="space-y-2">
|
<div class="grid grid-cols-2 gap-2">
|
||||||
<label class="text-xs text-dynamic-muted-foreground uppercase tracking-wider">Custom Colors</label>
|
<div class="space-y-1">
|
||||||
<div class="space-y-3">
|
<label class="text-[10px] text-dynamic-muted-foreground">Light</label>
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex gap-1">
|
||||||
<div class="flex items-center gap-2 flex-1">
|
<input type="color" id="designer-light-color" value="#3b82f6" class="w-6 h-6 rounded border border-dynamic-border cursor-pointer touch-target">
|
||||||
<div class="relative">
|
<input type="text" id="designer-light-color-text" value="#3b82f6" class="flex-1 px-1 py-1 bg-dynamic-background border border-dynamic-border rounded text-[10px] focus-ring font-mono touch-target" pattern="^#[0-9A-Fa-f]{6}$">
|
||||||
<input type="color" id="designer-light-color"
|
|
||||||
value="#3b82f6"
|
|
||||||
class="w-12 h-12 lg:w-10 lg:h-10 rounded-lg border-2 border-dynamic-border cursor-pointer hover:border-dynamic-primary transition-colors touch-target">
|
|
||||||
<div class="absolute inset-0 rounded-lg pointer-events-none" style="background: linear-gradient(135deg, transparent 50%, rgba(0,0,0,0.1) 50%)"></div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-1">
|
|
||||||
<label class="text-xs text-dynamic-muted-foreground block mb-1">Light Mode</label>
|
|
||||||
<input type="text" id="designer-light-color-text"
|
|
||||||
value="#3b82f6"
|
|
||||||
class="w-full px-3 py-2 lg:px-2 lg:py-1 bg-dynamic-background border border-dynamic-border rounded text-xs focus-ring font-mono touch-target"
|
|
||||||
pattern="^#[0-9A-Fa-f]{6}$">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-3">
|
</div>
|
||||||
<div class="flex items-center gap-2 flex-1">
|
<div class="space-y-1">
|
||||||
<div class="relative">
|
<label class="text-[10px] text-dynamic-muted-foreground">Dark</label>
|
||||||
<input type="color" id="designer-dark-color"
|
<div class="flex gap-1">
|
||||||
value="#60a5fa"
|
<input type="color" id="designer-dark-color" value="#60a5fa" class="w-6 h-6 rounded border border-dynamic-border cursor-pointer touch-target">
|
||||||
class="w-12 h-12 lg:w-10 lg:h-10 rounded-lg border-2 border-dynamic-border cursor-pointer hover:border-dynamic-primary transition-colors touch-target">
|
<input type="text" id="designer-dark-color-text" value="#60a5fa" class="flex-1 px-1 py-1 bg-dynamic-background border border-dynamic-border rounded text-[10px] focus-ring font-mono touch-target" pattern="^#[0-9A-Fa-f]{6}$">
|
||||||
<div class="absolute inset-0 rounded-lg pointer-events-none" style="background: linear-gradient(135deg, transparent 50%, rgba(255,255,255,0.1) 50%)"></div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-1">
|
|
||||||
<label class="text-xs text-dynamic-muted-foreground block mb-1">Dark Mode</label>
|
|
||||||
<input type="text" id="designer-dark-color-text"
|
|
||||||
value="#60a5fa"
|
|
||||||
class="w-full px-3 py-2 lg:px-2 lg:py-1 bg-dynamic-background border border-dynamic-border rounded text-xs focus-ring font-mono touch-target"
|
|
||||||
pattern="^#[0-9A-Fa-f]{6}$">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Height -->
|
||||||
|
<div class="space-y-1">
|
||||||
|
<label class="text-xs font-medium text-dynamic-muted-foreground">
|
||||||
|
Height: <span id="height-value" class="text-dynamic-foreground">400</span>px
|
||||||
|
</label>
|
||||||
|
<input type="range" id="designer-height"
|
||||||
|
class="w-full h-1.5 bg-dynamic-muted rounded-lg appearance-none cursor-pointer slider"
|
||||||
|
min="200" max="800" value="400" step="50">
|
||||||
|
<div class="flex justify-between text-[10px] text-dynamic-muted-foreground opacity-60">
|
||||||
|
<span>200px</span>
|
||||||
|
<span>800px</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Height -->
|
<!-- FEATURES SECTION -->
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<label class="text-sm font-medium text-dynamic-muted-foreground">
|
<h3 class="text-xs font-semibold text-dynamic-foreground uppercase tracking-wider border-b border-dynamic-border pb-1">Features</h3>
|
||||||
Height: <span id="height-value" class="text-dynamic-foreground">400</span>px
|
|
||||||
</label>
|
|
||||||
<input type="range" id="designer-height"
|
|
||||||
class="w-full h-2 bg-dynamic-muted rounded-lg appearance-none cursor-pointer slider"
|
|
||||||
min="200" max="800" value="400" step="50">
|
|
||||||
<div class="flex justify-between text-xs text-dynamic-muted-foreground">
|
|
||||||
<span>200px</span>
|
|
||||||
<span>800px</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- File Tree -->
|
<!-- File Tree -->
|
||||||
<div class="space-y-2">
|
<div class="space-y-1">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<label class="text-sm font-medium text-dynamic-muted-foreground">File Tree</label>
|
<label class="text-xs font-medium text-dynamic-muted-foreground">File Tree</label>
|
||||||
<label class="flex items-center space-x-1.5 text-xs">
|
<label class="flex items-center space-x-1 text-[10px]">
|
||||||
<input type="checkbox" id="designer-show-filetree" class="rounded border-dynamic-border w-3.5 h-3.5" checked>
|
<input type="checkbox" id="designer-show-filetree" class="rounded border-dynamic-border w-3 h-3" checked>
|
||||||
<span class="text-dynamic-muted-foreground">Show in preview</span>
|
<span class="text-dynamic-muted-foreground">Show</span>
|
||||||
</label>
|
</label>
|
||||||
|
</div>
|
||||||
|
<textarea id="designer-filetree"
|
||||||
|
class="w-full p-2 bg-dynamic-background border border-dynamic-border rounded text-[10px] resize-none focus-ring custom-scrollbar touch-target font-mono"
|
||||||
|
rows="4"
|
||||||
|
placeholder="index.html styles/main.css scripts/app.js components/header.vue"></textarea>
|
||||||
|
<p class="text-[9px] text-dynamic-muted-foreground opacity-60">
|
||||||
|
One per line. Use / for folders. Add * to highlight.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Diff View -->
|
||||||
|
<div class="space-y-1">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<label class="text-xs font-medium text-dynamic-muted-foreground">Diff View</label>
|
||||||
|
<label class="flex items-center space-x-1 text-[10px]">
|
||||||
|
<input type="checkbox" id="designer-show-diff" class="rounded border-dynamic-border w-3 h-3">
|
||||||
|
<span class="text-dynamic-muted-foreground">Show</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div id="diff-fields" class="space-y-2 hidden">
|
||||||
|
<div class="grid grid-cols-2 gap-2">
|
||||||
|
<div>
|
||||||
|
<label class="text-[10px] text-dynamic-muted-foreground">Filename</label>
|
||||||
|
<input type="text" id="designer-diff-filename"
|
||||||
|
class="w-full p-1.5 bg-dynamic-background border border-dynamic-border rounded text-[10px] focus-ring touch-target font-mono"
|
||||||
|
placeholder="file.tsx">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="text-[10px] text-dynamic-muted-foreground">Flash</label>
|
||||||
|
<select id="designer-flash-button" class="w-full p-1.5 bg-dynamic-background border border-dynamic-border rounded text-[10px] focus-ring touch-target">
|
||||||
|
<option value="none">None</option>
|
||||||
|
<option value="accept">Accept</option>
|
||||||
|
<option value="reject">Reject</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="text-[10px] text-dynamic-muted-foreground">Old Text</label>
|
||||||
|
<textarea id="designer-diff-old"
|
||||||
|
class="w-full p-2 bg-dynamic-background border border-dynamic-border rounded text-[10px] resize-none focus-ring custom-scrollbar touch-target font-mono"
|
||||||
|
rows="3"
|
||||||
|
placeholder="// Original code..."></textarea>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="text-[10px] text-dynamic-muted-foreground">New Text</label>
|
||||||
|
<textarea id="designer-diff-new"
|
||||||
|
class="w-full p-2 bg-dynamic-background border border-dynamic-border rounded text-[10px] resize-none focus-ring custom-scrollbar touch-target font-mono"
|
||||||
|
rows="3"
|
||||||
|
placeholder="// Updated code..."></textarea>
|
||||||
|
</div>
|
||||||
|
<p class="text-[9px] text-dynamic-muted-foreground opacity-50">
|
||||||
|
Keep short for URL sharing.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<textarea id="designer-filetree"
|
|
||||||
class="w-full p-3 bg-dynamic-background border border-dynamic-border rounded-lg text-sm resize-none focus-ring custom-scrollbar touch-target font-mono"
|
|
||||||
rows="6"
|
|
||||||
placeholder="Enter files (one per line): index.html styles/main.css scripts/app.js components/header.vue"></textarea>
|
|
||||||
<p class="text-xs text-dynamic-muted-foreground">
|
|
||||||
Enter filenames one per line. Use forward slashes for folders (e.g., folder/file.js).
|
|
||||||
Add * at the end of a filename to highlight it (e.g., main.js*)
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Generate Buttons - Fixed at bottom -->
|
<!-- Generate Buttons - Fixed at bottom -->
|
||||||
<div class="p-4 lg:p-6 space-y-3 border-t border-dynamic-border bg-dynamic-muted lg:pb-0">
|
<div class="p-3 lg:p-4 space-y-2 border-t border-dynamic-border bg-dynamic-muted">
|
||||||
<button id="generate-embed" class="w-full bg-dynamic-primary text-white p-3 lg:p-2 rounded-lg text-sm font-medium hover:opacity-90 transition-opacity touch-target">
|
<button id="generate-embed" class="w-full bg-dynamic-primary text-white p-2.5 rounded text-xs font-medium hover:opacity-90 transition-opacity touch-target">
|
||||||
Generate Embed Code
|
Generate Embed Code
|
||||||
</button>
|
</button>
|
||||||
<button id="reset-settings" class="text-[11px] text-dynamic-muted-foreground hover:text-dynamic-foreground transition-colors opacity-60 hover:opacity-100 touch-target">
|
<button id="reset-settings" class="text-[10px] text-dynamic-muted-foreground hover:text-dynamic-foreground transition-colors opacity-50 hover:opacity-100 touch-target">
|
||||||
Reset settings
|
Reset settings
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -26,7 +26,12 @@ class EmbedPreview {
|
|||||||
lightColor: this.params.lightColor || '#3b82f6',
|
lightColor: this.params.lightColor || '#3b82f6',
|
||||||
darkColor: this.params.darkColor || '#60a5fa',
|
darkColor: this.params.darkColor || '#60a5fa',
|
||||||
themeMode: this.params.themeMode || 'auto',
|
themeMode: this.params.themeMode || 'auto',
|
||||||
filetree: this.params.filetree ? decodeURIComponent(this.params.filetree).split('\n').filter(f => f.trim()) : []
|
filetree: this.params.filetree ? decodeURIComponent(this.params.filetree).split('\n').filter(f => f.trim()) : [],
|
||||||
|
showDiff: this.params.showDiff === 'true',
|
||||||
|
diffFilename: this.params.diffFilename || '',
|
||||||
|
diffOldText: this.params.diffOldText ? decodeURIComponent(this.params.diffOldText) : '',
|
||||||
|
diffNewText: this.params.diffNewText ? decodeURIComponent(this.params.diffNewText) : '',
|
||||||
|
flashButton: this.params.flashButton || 'none'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +39,7 @@ class EmbedPreview {
|
|||||||
this.setupColors();
|
this.setupColors();
|
||||||
this.setupElements();
|
this.setupElements();
|
||||||
this.render();
|
this.render();
|
||||||
|
this.setupResizeListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
setupColors() {
|
setupColors() {
|
||||||
@ -187,6 +193,7 @@ class EmbedPreview {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
this.renderDiffView();
|
||||||
this.renderContextPills();
|
this.renderContextPills();
|
||||||
this.renderPromptText();
|
this.renderPromptText();
|
||||||
this.renderSettingsPills();
|
this.renderSettingsPills();
|
||||||
@ -315,21 +322,21 @@ class EmbedPreview {
|
|||||||
|
|
||||||
createSettingPill(text, type) {
|
createSettingPill(text, type) {
|
||||||
const pill = document.createElement('div');
|
const pill = document.createElement('div');
|
||||||
pill.className = 'rounded-full text-xs font-medium flex items-center gap-1.5';
|
pill.className = 'rounded-full text-[10px] font-medium flex items-center gap-1';
|
||||||
|
|
||||||
let icon = '';
|
let icon = '';
|
||||||
|
|
||||||
// Use different styling based on pill type
|
// Use different styling based on pill type
|
||||||
if (type === 'mode') {
|
if (type === 'mode') {
|
||||||
// Mode pill keeps the background
|
// Mode pill keeps the background with reduced padding
|
||||||
if (this.isDarkMode) {
|
if (this.isDarkMode) {
|
||||||
pill.className += ' px-3 py-2 bg-dynamic-primary/20 text-dynamic-foreground border border-dynamic-primary/30';
|
pill.className += ' px-2 py-1 bg-dynamic-primary/20 text-dynamic-foreground border border-dynamic-primary/30';
|
||||||
} else {
|
} else {
|
||||||
pill.className += ' px-3 py-2 bg-dynamic-primary/10 text-dynamic-foreground border border-dynamic-primary/20';
|
pill.className += ' px-2 py-1 bg-dynamic-primary/10 text-dynamic-foreground border border-dynamic-primary/20';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Model, thinking, and max pills only have text color
|
// Model, thinking, and max pills only have text color
|
||||||
pill.className += ' pl-1 text-dynamic-primary';
|
pill.className += ' pl-0.5 text-dynamic-primary';
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -341,16 +348,16 @@ class EmbedPreview {
|
|||||||
const modeType = text.toLowerCase();
|
const modeType = text.toLowerCase();
|
||||||
switch (modeType) {
|
switch (modeType) {
|
||||||
case 'agent':
|
case 'agent':
|
||||||
icon = '<svg class="w-3 h-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M18.18 8.04c-.78-.84-1.92-1.54-3.18-1.54-1.44 0-2.7.93-3.48 2.25-.78-1.32-2.04-2.25-3.48-2.25-1.26 0-2.4.7-3.18 1.54-.87.94-1.36 2.11-1.36 3.46 0 1.35.49 2.52 1.36 3.46.78.84 1.92 1.54 3.18 1.54 1.44 0 2.7-.93 3.48-2.25.78 1.32 2.04 2.25 3.48 2.25 1.26 0 2.4-.7 3.18-1.54.87-.94 1.36-2.11 1.36-3.46 0-1.35-.49-2.52-1.36-3.46z"/></svg>';
|
icon = '<svg class="w-2.5 h-2.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M18.18 8.04c-.78-.84-1.92-1.54-3.18-1.54-1.44 0-2.7.93-3.48 2.25-.78-1.32-2.04-2.25-3.48-2.25-1.26 0-2.4.7-3.18 1.54-.87.94-1.36 2.11-1.36 3.46 0 1.35.49 2.52 1.36 3.46.78.84 1.92 1.54 3.18 1.54 1.44 0 2.7-.93 3.48-2.25.78 1.32 2.04 2.25 3.48 2.25 1.26 0 2.4-.7 3.18-1.54.87-.94 1.36-2.11 1.36-3.46 0-1.35-.49-2.52-1.36-3.46z"/></svg>';
|
||||||
break;
|
break;
|
||||||
case 'chat':
|
case 'chat':
|
||||||
icon = '<svg class="w-3 h-3" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M18 10c0 3.866-3.582 7-8 7a8.841 8.841 0 01-4.083-.98L2 17l1.338-3.123C2.493 12.767 2 11.434 2 10c0-3.866 3.582-7 8-7s8 3.134 8 7zM7 9H5v2h2V9zm8 0h-2v2h2V9zM9 9h2v2H9V9z" clip-rule="evenodd"/></svg>';
|
icon = '<svg class="w-2.5 h-2.5" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M18 10c0 3.866-3.582 7-8 7a8.841 8.841 0 01-4.083-.98L2 17l1.338-3.123C2.493 12.767 2 11.434 2 10c0-3.866 3.582-7 8-7s8 3.134 8 7zM7 9H5v2h2V9zm8 0h-2v2h2V9zM9 9h2v2H9V9z" clip-rule="evenodd"/></svg>';
|
||||||
break;
|
break;
|
||||||
case 'manual':
|
case 'manual':
|
||||||
icon = '<svg class="w-3 h-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 2v20M2 12h20"/><circle cx="12" cy="12" r="3" fill="currentColor"/></svg>';
|
icon = '<svg class="w-2.5 h-2.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 2v20M2 12h20"/><circle cx="12" cy="12" r="3" fill="currentColor"/></svg>';
|
||||||
break;
|
break;
|
||||||
case 'cloud':
|
case 'cloud':
|
||||||
icon = '<svg class="w-3 h-3" viewBox="0 0 20 20" fill="currentColor"><path d="M5.5 16a3.5 3.5 0 01-.369-6.98 4 4 0 117.753-1.977A4.5 4.5 0 1113.5 16h-8z"/></svg>';
|
icon = '<svg class="w-2.5 h-2.5" viewBox="0 0 20 20" fill="currentColor"><path d="M5.5 16a3.5 3.5 0 01-.369-6.98 4 4 0 117.753-1.977A4.5 4.5 0 1113.5 16h-8z"/></svg>';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
icon = '';
|
icon = '';
|
||||||
@ -360,12 +367,12 @@ class EmbedPreview {
|
|||||||
break;
|
break;
|
||||||
case 'thinking':
|
case 'thinking':
|
||||||
// Brain icon for thinking mode
|
// Brain icon for thinking mode
|
||||||
icon = '<svg class="w-3 h-3" viewBox="0 0 24 24" fill="currentColor"><path d="M19.864 8.465a3.505 3.505 0 0 0-3.03-4.449A3.005 3.005 0 0 0 14 2a2.98 2.98 0 0 0-2 .78A2.98 2.98 0 0 0 10 2c-1.301 0-2.41.831-2.825 2.015a3.505 3.505 0 0 0-3.039 4.45A4.028 4.028 0 0 0 2 12c0 1.075.428 2.086 1.172 2.832A4.067 4.067 0 0 0 3 16c0 1.957 1.412 3.59 3.306 3.934A3.515 3.515 0 0 0 9.5 22c.979 0 1.864-.407 2.5-1.059A3.484 3.484 0 0 0 14.5 22a3.51 3.51 0 0 0 3.19-2.06 4.006 4.006 0 0 0 3.138-5.108A4.003 4.003 0 0 0 22 12a4.028 4.028 0 0 0-2.136-3.535zM9.5 20c-.711 0-1.33-.504-1.47-1.198L7.818 18H7c-1.103 0-2-.897-2-2 0-.352.085-.682.253-.981l.456-.816-.784-.51A2.019 2.019 0 0 1 4 12c0-.977.723-1.824 1.682-1.972l1.693-.26-1.059-1.346a1.502 1.502 0 0 1 1.498-2.39L9 6.207V5a1 1 0 0 1 2 0v13.5c0 .827-.673 1.5-1.5 1.5zm9.575-6.308-.784.51.456.816c.168.3.253.63.253.982 0 1.103-.897 2-2.05 2h-.818l-.162.802A1.502 1.502 0 0 1 14.5 20c-.827 0-1.5-.673-1.5-1.5V5c0-.552.448-1 1-1s1 .448 1 1.05v1.207l1.186-.225a1.502 1.502 0 0 1 1.498 2.39l-1.059 1.347 1.693.26A2.002 2.002 0 0 1 20 12c0 .683-.346 1.315-.925 1.692z"></path></svg>';
|
icon = '<svg class="w-2.5 h-2.5" viewBox="0 0 24 24" fill="currentColor"><path d="M19.864 8.465a3.505 3.505 0 0 0-3.03-4.449A3.005 3.005 0 0 0 14 2a2.98 2.98 0 0 0-2 .78A2.98 2.98 0 0 0 10 2c-1.301 0-2.41.831-2.825 2.015a3.505 3.505 0 0 0-3.039 4.45A4.028 4.028 0 0 0 2 12c0 1.075.428 2.086 1.172 2.832A4.067 4.067 0 0 0 3 16c0 1.957 1.412 3.59 3.306 3.934A3.515 3.515 0 0 0 9.5 22c.979 0 1.864-.407 2.5-1.059A3.484 3.484 0 0 0 14.5 22a3.51 3.51 0 0 0 3.19-2.06 4.006 4.006 0 0 0 3.138-5.108A4.003 4.003 0 0 0 22 12a4.028 4.028 0 0 0-2.136-3.535zM9.5 20c-.711 0-1.33-.504-1.47-1.198L7.818 18H7c-1.103 0-2-.897-2-2 0-.352.085-.682.253-.981l.456-.816-.784-.51A2.019 2.019 0 0 1 4 12c0-.977.723-1.824 1.682-1.972l1.693-.26-1.059-1.346a1.502 1.502 0 0 1 1.498-2.39L9 6.207V5a1 1 0 0 1 2 0v13.5c0 .827-.673 1.5-1.5 1.5zm9.575-6.308-.784.51.456.816c.168.3.253.63.253.982 0 1.103-.897 2-2.05 2h-.818l-.162.802A1.502 1.502 0 0 1 14.5 20c-.827 0-1.5-.673-1.5-1.5V5c0-.552.448-1 1-1s1 .448 1 1.05v1.207l1.186-.225a1.502 1.502 0 0 1 1.498 2.39l-1.059 1.347 1.693.26A2.002 2.002 0 0 1 20 12c0 .683-.346 1.315-.925 1.692z"></path></svg>';
|
||||||
pill.innerHTML = icon + '<span>' + text + '</span>';
|
pill.innerHTML = icon + '<span>' + text + '</span>';
|
||||||
break;
|
break;
|
||||||
case 'max':
|
case 'max':
|
||||||
// Lightning bolt icon for MAX mode
|
// Lightning bolt icon for MAX mode
|
||||||
icon = '<svg class="w-3 h-3" viewBox="0 0 20 20" fill="currentColor"><path d="M11.3 1.046A1 1 0 0112 2v5h4a1 1 0 01.82 1.573l-7 10A1 1 0 018 18v-5H4a1 1 0 01-.82-1.573l7-10a1 1 0 011.12-.38z"/></svg>';
|
icon = '<svg class="w-2.5 h-2.5" viewBox="0 0 20 20" fill="currentColor"><path d="M11.3 1.046A1 1 0 0112 2v5h4a1 1 0 01.82 1.573l-7 10A1 1 0 018 18v-5H4a1 1 0 01-.82-1.573l7-10a1 1 0 011.12-.38z"/></svg>';
|
||||||
pill.innerHTML = icon + '<span>' + text + '</span>';
|
pill.innerHTML = icon + '<span>' + text + '</span>';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -373,8 +380,171 @@ class EmbedPreview {
|
|||||||
return pill;
|
return pill;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setupResizeListener() {
|
||||||
|
let resizeTimeout;
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
clearTimeout(resizeTimeout);
|
||||||
|
resizeTimeout = setTimeout(() => {
|
||||||
|
this.renderDiffView();
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
renderDiffView() {
|
||||||
|
const diffView = document.getElementById('diff-view');
|
||||||
|
const diffViewInline = document.getElementById('diff-view-inline');
|
||||||
|
const promptText = document.getElementById('prompt-text');
|
||||||
|
if (!diffView || !diffViewInline) return;
|
||||||
|
|
||||||
|
const viewportHeight = window.innerHeight;
|
||||||
|
const isCompact = viewportHeight < 400;
|
||||||
|
|
||||||
|
if (this.config.showDiff && (this.config.diffOldText || this.config.diffNewText)) {
|
||||||
|
// Determine which view to show based on viewport height
|
||||||
|
if (isCompact) {
|
||||||
|
// Show floating diff view
|
||||||
|
diffView.classList.remove('hidden');
|
||||||
|
diffView.classList.add('diff-enter');
|
||||||
|
diffViewInline.classList.add('hidden');
|
||||||
|
this.setupDiffContent('diff-view');
|
||||||
|
} else {
|
||||||
|
// Show inline diff view
|
||||||
|
diffViewInline.classList.remove('hidden');
|
||||||
|
diffView.classList.add('hidden');
|
||||||
|
this.setupDiffContent('diff-view-inline');
|
||||||
|
// Reset margin when switching to inline view
|
||||||
|
if (promptText) {
|
||||||
|
promptText.style.marginTop = '0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
diffView.classList.add('hidden');
|
||||||
|
diffViewInline.classList.add('hidden');
|
||||||
|
// Reset margin when diff is hidden
|
||||||
|
if (promptText) {
|
||||||
|
promptText.style.marginTop = '0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setupDiffContent(containerId) {
|
||||||
|
const container = document.getElementById(containerId);
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
// Count lines in old and new content
|
||||||
|
const oldLines = this.config.diffOldText ? this.config.diffOldText.split('\n').length : 0;
|
||||||
|
const newLines = this.config.diffNewText ? this.config.diffNewText.split('\n').length : 0;
|
||||||
|
|
||||||
|
// Set filename with line counts
|
||||||
|
const filenameElement = container.querySelector('[id$="-filename"]');
|
||||||
|
if (filenameElement) {
|
||||||
|
const filename = this.config.diffFilename || 'untitled';
|
||||||
|
filenameElement.innerHTML = `
|
||||||
|
<span>${filename}</span>
|
||||||
|
<span class="ml-2 text-[10px] font-mono">
|
||||||
|
<span class="text-green-600 dark:text-green-400">+${newLines}</span>
|
||||||
|
<span class="text-red-600 dark:text-red-400">-${oldLines}</span>
|
||||||
|
</span>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set diff content
|
||||||
|
const oldContent = container.querySelector('[id$="-old-content"]');
|
||||||
|
const newContent = container.querySelector('[id$="-new-content"]');
|
||||||
|
|
||||||
|
if (oldContent) {
|
||||||
|
oldContent.textContent = this.config.diffOldText || '(empty)';
|
||||||
|
// Update colors based on dark mode
|
||||||
|
if (this.isDarkMode) {
|
||||||
|
oldContent.style.backgroundColor = 'rgba(127, 29, 29, 0.15)';
|
||||||
|
oldContent.style.color = '#fca5a5';
|
||||||
|
oldContent.style.borderColor = 'rgba(127, 29, 29, 0.3)';
|
||||||
|
} else {
|
||||||
|
oldContent.style.backgroundColor = 'rgba(254, 226, 226, 0.7)';
|
||||||
|
oldContent.style.color = '#b91c1c';
|
||||||
|
oldContent.style.borderColor = 'rgba(252, 165, 165, 0.5)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newContent) {
|
||||||
|
newContent.textContent = this.config.diffNewText || '(empty)';
|
||||||
|
// Update colors based on dark mode
|
||||||
|
if (this.isDarkMode) {
|
||||||
|
newContent.style.backgroundColor = 'rgba(20, 83, 45, 0.15)';
|
||||||
|
newContent.style.color = '#86efac';
|
||||||
|
newContent.style.borderColor = 'rgba(20, 83, 45, 0.3)';
|
||||||
|
} else {
|
||||||
|
newContent.style.backgroundColor = 'rgba(220, 252, 231, 0.7)';
|
||||||
|
newContent.style.color = '#15803d';
|
||||||
|
newContent.style.borderColor = 'rgba(134, 239, 172, 0.5)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply flash animation to buttons if configured
|
||||||
|
const acceptButton = container.querySelector('[id$="-accept-diff"]');
|
||||||
|
const rejectButton = container.querySelector('[id$="-reject-diff"]');
|
||||||
|
|
||||||
|
if (this.config.flashButton === 'accept' && acceptButton) {
|
||||||
|
acceptButton.classList.add('flash-animation');
|
||||||
|
// Remove from reject button if it exists
|
||||||
|
if (rejectButton) rejectButton.classList.remove('flash-animation');
|
||||||
|
} else if (this.config.flashButton === 'reject' && rejectButton) {
|
||||||
|
rejectButton.classList.add('flash-animation');
|
||||||
|
// Remove from accept button if it exists
|
||||||
|
if (acceptButton) acceptButton.classList.remove('flash-animation');
|
||||||
|
} else {
|
||||||
|
// Remove animation from both if 'none'
|
||||||
|
if (acceptButton) acceptButton.classList.remove('flash-animation');
|
||||||
|
if (rejectButton) rejectButton.classList.remove('flash-animation');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup toggle button for floating view only
|
||||||
|
if (containerId === 'diff-view') {
|
||||||
|
const toggleButton = container.querySelector('#toggle-diff');
|
||||||
|
const diffContent = container.querySelector('#diff-content');
|
||||||
|
const promptText = document.getElementById('prompt-text');
|
||||||
|
|
||||||
|
if (toggleButton && diffContent && promptText) {
|
||||||
|
// Remove existing listeners
|
||||||
|
const newToggleButton = toggleButton.cloneNode(true);
|
||||||
|
toggleButton.parentNode.replaceChild(newToggleButton, toggleButton);
|
||||||
|
|
||||||
|
// Set initial state - collapsed when compact
|
||||||
|
let isExpanded = false;
|
||||||
|
diffContent.style.maxHeight = '0';
|
||||||
|
diffContent.style.overflow = 'hidden';
|
||||||
|
newToggleButton.querySelector('svg').style.transform = 'rotate(-90deg)';
|
||||||
|
|
||||||
|
// Function to update prompt margin based on diff view height
|
||||||
|
const updatePromptMargin = () => {
|
||||||
|
const diffHeight = container.offsetHeight;
|
||||||
|
promptText.parentElement.style.paddingTop = `${diffHeight + 16}px`; // 16px for some breathing room
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set initial margin
|
||||||
|
setTimeout(updatePromptMargin, 0);
|
||||||
|
|
||||||
|
newToggleButton.addEventListener('click', () => {
|
||||||
|
isExpanded = !isExpanded;
|
||||||
|
|
||||||
|
if (isExpanded) {
|
||||||
|
diffContent.style.maxHeight = diffContent.scrollHeight + 'px';
|
||||||
|
newToggleButton.querySelector('svg').style.transform = 'rotate(0deg)';
|
||||||
|
// Update margin after animation
|
||||||
|
setTimeout(updatePromptMargin, 300);
|
||||||
|
} else {
|
||||||
|
diffContent.style.maxHeight = '0';
|
||||||
|
diffContent.style.overflow = 'hidden';
|
||||||
|
newToggleButton.querySelector('svg').style.transform = 'rotate(-90deg)';
|
||||||
|
// Update margin after animation
|
||||||
|
setTimeout(updatePromptMargin, 300);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
highlightMentions(text) {
|
highlightMentions(text) {
|
||||||
return text.replace(/@(\w+)/g, '<span class="mention">@$1</span>');
|
return text.replaceAll(/@(https?:\/\/[^\s]+.*?|\w+\.\w+|\w+)/g, '<span class="mention">@$1</span>');
|
||||||
}
|
}
|
||||||
|
|
||||||
capitalizeFirst(str) {
|
capitalizeFirst(str) {
|
||||||
|
428
embed-script.js
428
embed-script.js
@ -34,7 +34,12 @@ class EmbedDesigner {
|
|||||||
height: this.params.height || savedConfig.height || '400',
|
height: this.params.height || savedConfig.height || '400',
|
||||||
themeMode: this.params.themeMode || savedConfig.themeMode || 'auto',
|
themeMode: this.params.themeMode || savedConfig.themeMode || 'auto',
|
||||||
filetree: this.params.filetree ? decodeURIComponent(this.params.filetree).split('\n').filter(f => f.trim()) : (savedConfig.filetree || []),
|
filetree: this.params.filetree ? decodeURIComponent(this.params.filetree).split('\n').filter(f => f.trim()) : (savedConfig.filetree || []),
|
||||||
showFiletree: savedConfig.showFiletree !== undefined ? savedConfig.showFiletree : true
|
showFiletree: savedConfig.showFiletree !== undefined ? savedConfig.showFiletree : true,
|
||||||
|
showDiff: this.params.showDiff === 'true' || savedConfig.showDiff || false,
|
||||||
|
diffFilename: this.params.diffFilename || savedConfig.diffFilename || '',
|
||||||
|
diffOldText: this.params.diffOldText ? decodeURIComponent(this.params.diffOldText) : (savedConfig.diffOldText || ''),
|
||||||
|
diffNewText: this.params.diffNewText ? decodeURIComponent(this.params.diffNewText) : (savedConfig.diffNewText || ''),
|
||||||
|
flashButton: this.params.flashButton || savedConfig.flashButton || 'none'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +62,12 @@ class EmbedDesigner {
|
|||||||
height: '400',
|
height: '400',
|
||||||
themeMode: 'auto',
|
themeMode: 'auto',
|
||||||
filetree: [],
|
filetree: [],
|
||||||
showFiletree: true
|
showFiletree: true,
|
||||||
|
showDiff: false,
|
||||||
|
diffFilename: '',
|
||||||
|
diffOldText: '',
|
||||||
|
diffNewText: '',
|
||||||
|
flashButton: 'none'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +91,12 @@ class EmbedDesigner {
|
|||||||
height: config.height || '400',
|
height: config.height || '400',
|
||||||
themeMode: config.themeMode || 'auto',
|
themeMode: config.themeMode || 'auto',
|
||||||
filetree: config.filetree || [],
|
filetree: config.filetree || [],
|
||||||
showFiletree: config.showFiletree !== undefined ? config.showFiletree : true
|
showFiletree: config.showFiletree !== undefined ? config.showFiletree : true,
|
||||||
|
showDiff: config.showDiff || false,
|
||||||
|
diffFilename: config.diffFilename || '',
|
||||||
|
diffOldText: config.diffOldText || '',
|
||||||
|
diffNewText: config.diffNewText || '',
|
||||||
|
flashButton: config.flashButton || 'none'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -177,6 +192,27 @@ class EmbedDesigner {
|
|||||||
darkColorPicker.value = this.config.darkColor;
|
darkColorPicker.value = this.config.darkColor;
|
||||||
darkColorText.value = this.config.darkColor;
|
darkColorText.value = this.config.darkColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up diff view
|
||||||
|
const showDiffCheckbox = document.getElementById('designer-show-diff');
|
||||||
|
const diffFields = document.getElementById('diff-fields');
|
||||||
|
if (showDiffCheckbox) {
|
||||||
|
showDiffCheckbox.checked = this.config.showDiff || false;
|
||||||
|
if (diffFields) {
|
||||||
|
diffFields.classList.toggle('hidden', !this.config.showDiff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set diff field values
|
||||||
|
const diffFilename = document.getElementById('designer-diff-filename');
|
||||||
|
const diffOldText = document.getElementById('designer-diff-old');
|
||||||
|
const diffNewText = document.getElementById('designer-diff-new');
|
||||||
|
const flashButton = document.getElementById('designer-flash-button');
|
||||||
|
|
||||||
|
if (diffFilename) diffFilename.value = this.config.diffFilename || '';
|
||||||
|
if (diffOldText) diffOldText.value = this.config.diffOldText || '';
|
||||||
|
if (diffNewText) diffNewText.value = this.config.diffNewText || '';
|
||||||
|
if (flashButton) flashButton.value = this.config.flashButton || 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
updateThemeModeButtons() {
|
updateThemeModeButtons() {
|
||||||
@ -195,7 +231,7 @@ class EmbedDesigner {
|
|||||||
|
|
||||||
setupDesignerEvents() {
|
setupDesignerEvents() {
|
||||||
// Form changes update preview
|
// Form changes update preview
|
||||||
['designer-prompt', 'designer-context', 'designer-mode-select', 'designer-thinking', 'designer-max', 'designer-filetree', 'designer-show-filetree'].forEach(id => {
|
['designer-prompt', 'designer-context', 'designer-mode-select', 'designer-thinking', 'designer-max', 'designer-filetree', 'designer-show-filetree', 'designer-diff-filename', 'designer-diff-old', 'designer-diff-new', 'designer-flash-button'].forEach(id => {
|
||||||
const element = document.getElementById(id);
|
const element = document.getElementById(id);
|
||||||
if (element) {
|
if (element) {
|
||||||
element.addEventListener('input', () => this.updateConfigFromForm());
|
element.addEventListener('input', () => this.updateConfigFromForm());
|
||||||
@ -203,6 +239,18 @@ class EmbedDesigner {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Diff view toggle
|
||||||
|
const showDiffCheckbox = document.getElementById('designer-show-diff');
|
||||||
|
const diffFields = document.getElementById('diff-fields');
|
||||||
|
if (showDiffCheckbox) {
|
||||||
|
showDiffCheckbox.addEventListener('change', (e) => {
|
||||||
|
if (diffFields) {
|
||||||
|
diffFields.classList.toggle('hidden', !e.target.checked);
|
||||||
|
}
|
||||||
|
this.updateConfigFromForm();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Theme mode buttons
|
// Theme mode buttons
|
||||||
document.querySelectorAll('.theme-mode-btn').forEach(btn => {
|
document.querySelectorAll('.theme-mode-btn').forEach(btn => {
|
||||||
btn.addEventListener('click', (e) => {
|
btn.addEventListener('click', (e) => {
|
||||||
@ -329,7 +377,11 @@ class EmbedDesigner {
|
|||||||
height: '400',
|
height: '400',
|
||||||
themeMode: 'auto',
|
themeMode: 'auto',
|
||||||
filetree: [],
|
filetree: [],
|
||||||
showFiletree: true
|
showFiletree: true,
|
||||||
|
showDiff: false,
|
||||||
|
diffFilename: '',
|
||||||
|
diffOldText: '',
|
||||||
|
diffNewText: ''
|
||||||
};
|
};
|
||||||
// Update UI to reflect defaults
|
// Update UI to reflect defaults
|
||||||
this.setupDesignerElements();
|
this.setupDesignerElements();
|
||||||
@ -338,14 +390,37 @@ class EmbedDesigner {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Example buttons
|
// Example select
|
||||||
document.getElementById('vibe-example').addEventListener('click', () => {
|
const exampleSelect = document.getElementById('example-select');
|
||||||
this.loadVibeExample();
|
if (exampleSelect) {
|
||||||
});
|
exampleSelect.addEventListener('change', (e) => {
|
||||||
|
const example = e.target.value;
|
||||||
document.getElementById('chat-example').addEventListener('click', () => {
|
if (example) {
|
||||||
this.loadChatExample();
|
switch (example) {
|
||||||
});
|
case 'vibe-coding':
|
||||||
|
this.loadVibeCodingExample();
|
||||||
|
break;
|
||||||
|
case 'vibe-coding-diff':
|
||||||
|
this.loadVibeCodingDiffExample();
|
||||||
|
break;
|
||||||
|
case 'chatgpt':
|
||||||
|
this.loadChatGPTExample();
|
||||||
|
break;
|
||||||
|
case 'claude':
|
||||||
|
this.loadClaudeExample();
|
||||||
|
break;
|
||||||
|
case 'image-analysis':
|
||||||
|
this.loadImageAnalysisExample();
|
||||||
|
break;
|
||||||
|
case 'api-design':
|
||||||
|
this.loadAPIDesignExample();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Reset select to placeholder after loading
|
||||||
|
exampleSelect.value = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Modal events
|
// Modal events
|
||||||
document.getElementById('close-modal').addEventListener('click', () => this.hideEmbedModal());
|
document.getElementById('close-modal').addEventListener('click', () => this.hideEmbedModal());
|
||||||
@ -383,7 +458,12 @@ class EmbedDesigner {
|
|||||||
height: heightSlider ? heightSlider.value : '400',
|
height: heightSlider ? heightSlider.value : '400',
|
||||||
themeMode: this.config.themeMode || 'auto',
|
themeMode: this.config.themeMode || 'auto',
|
||||||
filetree: document.getElementById('designer-filetree').value.split('\n').map(f => f.trim()).filter(f => f),
|
filetree: document.getElementById('designer-filetree').value.split('\n').map(f => f.trim()).filter(f => f),
|
||||||
showFiletree: document.getElementById('designer-show-filetree').checked
|
showFiletree: document.getElementById('designer-show-filetree').checked,
|
||||||
|
showDiff: document.getElementById('designer-show-diff').checked,
|
||||||
|
diffFilename: document.getElementById('designer-diff-filename').value,
|
||||||
|
diffOldText: document.getElementById('designer-diff-old').value,
|
||||||
|
diffNewText: document.getElementById('designer-diff-new').value,
|
||||||
|
flashButton: document.getElementById('designer-flash-button').value
|
||||||
};
|
};
|
||||||
|
|
||||||
this.updatePreview();
|
this.updatePreview();
|
||||||
@ -457,6 +537,20 @@ class EmbedDesigner {
|
|||||||
if (this.config.darkColor !== '#60a5fa') params.set('darkColor', this.config.darkColor);
|
if (this.config.darkColor !== '#60a5fa') params.set('darkColor', this.config.darkColor);
|
||||||
if (this.config.themeMode !== 'auto') params.set('themeMode', this.config.themeMode);
|
if (this.config.themeMode !== 'auto') params.set('themeMode', this.config.themeMode);
|
||||||
if (this.config.showFiletree && this.config.filetree && this.config.filetree.length > 0) params.set('filetree', encodeURIComponent(this.config.filetree.join('\n')));
|
if (this.config.showFiletree && this.config.filetree && this.config.filetree.length > 0) params.set('filetree', encodeURIComponent(this.config.filetree.join('\n')));
|
||||||
|
if (this.config.showDiff) {
|
||||||
|
params.set('showDiff', 'true');
|
||||||
|
if (this.config.diffFilename) params.set('diffFilename', this.config.diffFilename);
|
||||||
|
if (this.config.flashButton && this.config.flashButton !== 'none') params.set('flashButton', this.config.flashButton);
|
||||||
|
// Truncate diff text if too long to prevent URL length issues
|
||||||
|
if (this.config.diffOldText) {
|
||||||
|
const truncated = this.config.diffOldText.substring(0, 100);
|
||||||
|
params.set('diffOldText', encodeURIComponent(truncated)+'...');
|
||||||
|
}
|
||||||
|
if (this.config.diffNewText) {
|
||||||
|
const truncated = this.config.diffNewText.substring(0, 100);
|
||||||
|
params.set('diffNewText', encodeURIComponent(truncated)+'...');
|
||||||
|
}
|
||||||
|
}
|
||||||
params.set('preview', 'true');
|
params.set('preview', 'true');
|
||||||
|
|
||||||
return `/embed-preview/?${params.toString()}`;
|
return `/embed-preview/?${params.toString()}`;
|
||||||
@ -474,6 +568,20 @@ class EmbedDesigner {
|
|||||||
if (this.config.darkColor !== '#60a5fa') params.set('darkColor', this.config.darkColor);
|
if (this.config.darkColor !== '#60a5fa') params.set('darkColor', this.config.darkColor);
|
||||||
if (this.config.themeMode !== 'auto') params.set('themeMode', this.config.themeMode);
|
if (this.config.themeMode !== 'auto') params.set('themeMode', this.config.themeMode);
|
||||||
if (this.config.showFiletree && this.config.filetree && this.config.filetree.length > 0) params.set('filetree', encodeURIComponent(this.config.filetree.join('\n')));
|
if (this.config.showFiletree && this.config.filetree && this.config.filetree.length > 0) params.set('filetree', encodeURIComponent(this.config.filetree.join('\n')));
|
||||||
|
if (this.config.showDiff) {
|
||||||
|
params.set('showDiff', 'true');
|
||||||
|
if (this.config.diffFilename) params.set('diffFilename', this.config.diffFilename);
|
||||||
|
if (this.config.flashButton && this.config.flashButton !== 'none') params.set('flashButton', this.config.flashButton);
|
||||||
|
// Truncate diff text if too long to prevent URL length issues
|
||||||
|
if (this.config.diffOldText) {
|
||||||
|
const truncated = this.config.diffOldText.substring(0, 150);
|
||||||
|
params.set('diffOldText', encodeURIComponent(truncated));
|
||||||
|
}
|
||||||
|
if (this.config.diffNewText) {
|
||||||
|
const truncated = this.config.diffNewText.substring(0, 150);
|
||||||
|
params.set('diffNewText', encodeURIComponent(truncated));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return `${window.location.origin}/embed-preview/?${params.toString()}`;
|
return `${window.location.origin}/embed-preview/?${params.toString()}`;
|
||||||
}
|
}
|
||||||
@ -554,42 +662,26 @@ class EmbedDesigner {
|
|||||||
}, duration);
|
}, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadVibeExample() {
|
loadVibeCodingExample() {
|
||||||
|
// Vibe coding example WITHOUT diff
|
||||||
// Set vibe coding example values
|
// Set vibe coding example values
|
||||||
document.getElementById('designer-prompt').value =
|
document.getElementById('designer-prompt').value =
|
||||||
`I'm working on a React e-commerce app. The current ProductList component is getting messy with too much logic.
|
`Refactor my React ProductList component:
|
||||||
|
- Extract filtering logic to custom hook
|
||||||
|
- Split into smaller components
|
||||||
|
- Add TypeScript types
|
||||||
|
- Implement virtualization
|
||||||
|
|
||||||
Can you help me refactor it to:
|
Currently handles display, filtering, sorting, and pagination in one file.
|
||||||
1. Extract the filtering logic into a custom hook
|
|
||||||
2. Split the large component into smaller, reusable pieces
|
|
||||||
3. Add proper TypeScript types
|
|
||||||
4. Implement virtualization for better performance with large product lists
|
|
||||||
|
|
||||||
The component currently handles products display, filtering by category/price, sorting, and pagination all in one file. I want a cleaner architecture.`;
|
@web Check React Query docs for data fetching patterns.`;
|
||||||
|
|
||||||
document.getElementById('designer-context').value = '@codebase, ProductList.tsx, components/, hooks/';
|
document.getElementById('designer-context').value = '@codebase, ProductList.tsx';
|
||||||
document.getElementById('designer-filetree').value =
|
document.getElementById('designer-filetree').value =
|
||||||
`src/
|
`src/components/ProductList.tsx*
|
||||||
src/components/
|
|
||||||
src/components/ProductList.tsx*
|
|
||||||
src/components/ProductCard.tsx
|
src/components/ProductCard.tsx
|
||||||
src/components/ProductGrid.tsx
|
|
||||||
src/components/Filters/
|
|
||||||
src/components/Filters/CategoryFilter.tsx
|
|
||||||
src/components/Filters/PriceRangeFilter.tsx
|
|
||||||
src/components/Filters/index.tsx
|
|
||||||
src/hooks/
|
|
||||||
src/hooks/useProducts.ts
|
src/hooks/useProducts.ts
|
||||||
src/hooks/useFilters.ts
|
src/types/product.ts`;
|
||||||
src/hooks/useInfiniteScroll.ts
|
|
||||||
src/types/
|
|
||||||
src/types/product.ts
|
|
||||||
src/api/
|
|
||||||
src/api/products.ts
|
|
||||||
src/utils/
|
|
||||||
src/utils/formatters.ts
|
|
||||||
package.json
|
|
||||||
tsconfig.json`;
|
|
||||||
|
|
||||||
// Set vibe coding settings
|
// Set vibe coding settings
|
||||||
document.getElementById('designer-model').value = 'Claude 4 Opus';
|
document.getElementById('designer-model').value = 'Claude 4 Opus';
|
||||||
@ -618,30 +710,98 @@ tsconfig.json`;
|
|||||||
this.config.themeMode = 'dark';
|
this.config.themeMode = 'dark';
|
||||||
this.updateThemeModeButtons();
|
this.updateThemeModeButtons();
|
||||||
|
|
||||||
|
// No diff for this example
|
||||||
|
document.getElementById('designer-show-diff').checked = false;
|
||||||
|
document.getElementById('diff-fields').classList.add('hidden');
|
||||||
|
document.getElementById('designer-flash-button').value = 'none';
|
||||||
|
|
||||||
// Update config from form
|
// Update config from form
|
||||||
this.updateConfigFromForm();
|
this.updateConfigFromForm();
|
||||||
|
|
||||||
this.showNotification('Vibe coding example loaded!');
|
this.showNotification('Vibe coding example loaded!');
|
||||||
}
|
}
|
||||||
|
|
||||||
loadChatExample() {
|
loadVibeCodingDiffExample() {
|
||||||
// Set chat example values
|
// Vibe coding WITH diff - user giving feedback on suggested changes
|
||||||
|
document.getElementById('designer-prompt').value =
|
||||||
|
`Actually, don't use Error | null for the error state. Instead:
|
||||||
|
- Create a custom ApiError type with code, message, and retry()
|
||||||
|
- Add an AbortController for request cancellation
|
||||||
|
- Include error boundary integration
|
||||||
|
- Show me how to handle network vs API errors differently
|
||||||
|
|
||||||
|
Also add a refetch function that the UI can call.`;
|
||||||
|
|
||||||
|
document.getElementById('designer-context').value = '@codebase, useProducts.ts';
|
||||||
|
document.getElementById('designer-filetree').value =
|
||||||
|
`src/hooks/useProducts.ts*
|
||||||
|
src/types/errors.ts
|
||||||
|
src/utils/api.ts`;
|
||||||
|
|
||||||
|
// Set same settings as regular vibe coding
|
||||||
|
document.getElementById('designer-model').value = 'Claude 4 Opus';
|
||||||
|
document.getElementById('designer-mode-select').value = 'agent';
|
||||||
|
document.getElementById('designer-thinking').checked = true;
|
||||||
|
document.getElementById('designer-max').checked = true;
|
||||||
|
document.getElementById('designer-show-filetree').checked = true;
|
||||||
|
|
||||||
|
// Set height and colors
|
||||||
|
const heightSlider = document.getElementById('designer-height');
|
||||||
|
const heightValue = document.getElementById('height-value');
|
||||||
|
if (heightSlider) {
|
||||||
|
heightSlider.value = '500';
|
||||||
|
if (heightValue) {
|
||||||
|
heightValue.textContent = '500';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('designer-light-color').value = '#8b5cf6';
|
||||||
|
document.getElementById('designer-light-color-text').value = '#8b5cf6';
|
||||||
|
document.getElementById('designer-dark-color').value = '#a78bfa';
|
||||||
|
document.getElementById('designer-dark-color-text').value = '#a78bfa';
|
||||||
|
|
||||||
|
this.config.themeMode = 'dark';
|
||||||
|
this.updateThemeModeButtons();
|
||||||
|
|
||||||
|
// Add diff view showing the previous suggestion
|
||||||
|
document.getElementById('designer-show-diff').checked = true;
|
||||||
|
document.getElementById('diff-fields').classList.remove('hidden');
|
||||||
|
document.getElementById('designer-diff-filename').value = 'useProducts.ts';
|
||||||
|
document.getElementById('designer-diff-old').value =
|
||||||
|
`const [products, setProducts] = useState([]);
|
||||||
|
const [loading, setLoading] = useState(true);`;
|
||||||
|
document.getElementById('designer-diff-new').value =
|
||||||
|
`const [products, setProducts] = useState<Product[]>([]);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [error, setError] = useState<Error | null>(null);`;
|
||||||
|
|
||||||
|
// Flash accept button for this example with diff
|
||||||
|
document.getElementById('designer-flash-button').value = 'accept';
|
||||||
|
|
||||||
|
// Update config from form
|
||||||
|
this.updateConfigFromForm();
|
||||||
|
|
||||||
|
this.showNotification('Vibe coding with diff loaded!');
|
||||||
|
}
|
||||||
|
|
||||||
|
loadChatGPTExample() {
|
||||||
|
// ChatGPT example with green colors
|
||||||
document.getElementById('designer-prompt').value =
|
document.getElementById('designer-prompt').value =
|
||||||
`I'm planning a dinner party for 8 people this weekend. One person is vegetarian, another is gluten-free, and I want to make something impressive but not too complicated.
|
`I'm planning a dinner party for 8 people this weekend. One person is vegetarian, another is gluten-free, and I want to make something impressive but not too complicated.
|
||||||
|
|
||||||
Can you suggest a menu with appetizers, main course, and dessert that would work for everyone? I have about 4 hours to prepare everything and a moderate cooking skill level.`;
|
Can you suggest a menu with appetizers, main course, and dessert that would work for everyone? I have about 4 hours to prepare everything and a moderate cooking skill level.`;
|
||||||
|
|
||||||
document.getElementById('designer-context').value = '#Screenshot Kitchen Layout.png, Recipes Collection.pdf';
|
document.getElementById('designer-context').value = '#Kitchen Layout.png, #Pantry Inventory.jpg';
|
||||||
document.getElementById('designer-filetree').value = '';
|
document.getElementById('designer-filetree').value = '';
|
||||||
|
|
||||||
// Set chat settings
|
// ChatGPT settings
|
||||||
document.getElementById('designer-model').value = 'GPT 4o';
|
document.getElementById('designer-model').value = 'GPT 4o';
|
||||||
document.getElementById('designer-mode-select').value = 'chat';
|
document.getElementById('designer-mode-select').value = 'chat';
|
||||||
document.getElementById('designer-thinking').checked = false;
|
document.getElementById('designer-thinking').checked = false;
|
||||||
document.getElementById('designer-max').checked = false;
|
document.getElementById('designer-max').checked = false;
|
||||||
document.getElementById('designer-show-filetree').checked = false;
|
document.getElementById('designer-show-filetree').checked = false;
|
||||||
|
|
||||||
// Set height and colors for chat example
|
// Set height and colors for ChatGPT
|
||||||
const heightSlider = document.getElementById('designer-height');
|
const heightSlider = document.getElementById('designer-height');
|
||||||
const heightValue = document.getElementById('height-value');
|
const heightValue = document.getElementById('height-value');
|
||||||
if (heightSlider) {
|
if (heightSlider) {
|
||||||
@ -651,20 +811,188 @@ Can you suggest a menu with appetizers, main course, and dessert that would work
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set friendly color scheme (green)
|
// ChatGPT green color scheme
|
||||||
document.getElementById('designer-light-color').value = '#10b981';
|
document.getElementById('designer-light-color').value = '#10b981';
|
||||||
document.getElementById('designer-light-color-text').value = '#10b981';
|
document.getElementById('designer-light-color-text').value = '#10b981';
|
||||||
document.getElementById('designer-dark-color').value = '#34d399';
|
document.getElementById('designer-dark-color').value = '#34d399';
|
||||||
document.getElementById('designer-dark-color-text').value = '#34d399';
|
document.getElementById('designer-dark-color-text').value = '#34d399';
|
||||||
|
|
||||||
// Set light theme mode for chat
|
// Light theme for ChatGPT
|
||||||
this.config.themeMode = 'light';
|
this.config.themeMode = 'light';
|
||||||
this.updateThemeModeButtons();
|
this.updateThemeModeButtons();
|
||||||
|
|
||||||
|
// Clear diff view
|
||||||
|
document.getElementById('designer-show-diff').checked = false;
|
||||||
|
document.getElementById('diff-fields').classList.add('hidden');
|
||||||
|
document.getElementById('designer-flash-button').value = 'none';
|
||||||
|
|
||||||
// Update config from form
|
// Update config from form
|
||||||
this.updateConfigFromForm();
|
this.updateConfigFromForm();
|
||||||
|
|
||||||
this.showNotification('Chat example loaded!');
|
this.showNotification('ChatGPT example loaded!');
|
||||||
|
}
|
||||||
|
|
||||||
|
loadClaudeExample() {
|
||||||
|
// Claude example with orange colors - daily usage
|
||||||
|
document.getElementById('designer-prompt').value =
|
||||||
|
`Help me write a professional email to decline a job offer while keeping the door open for future opportunities.
|
||||||
|
|
||||||
|
Context:
|
||||||
|
- Received offer from TechCorp as Senior Engineer
|
||||||
|
- Great team and compensation, but role doesn't align with my career goals
|
||||||
|
- Want to maintain good relationship with the hiring manager Sarah
|
||||||
|
- Interested in their upcoming ML team expansion next year
|
||||||
|
|
||||||
|
Keep it warm but professional, around 150-200 words.`;
|
||||||
|
|
||||||
|
document.getElementById('designer-context').value = '';
|
||||||
|
document.getElementById('designer-filetree').value = '';
|
||||||
|
|
||||||
|
// Claude settings
|
||||||
|
document.getElementById('designer-model').value = 'Claude 3.7 Sonnet';
|
||||||
|
document.getElementById('designer-mode-select').value = 'chat';
|
||||||
|
document.getElementById('designer-thinking').checked = false;
|
||||||
|
document.getElementById('designer-max').checked = false;
|
||||||
|
document.getElementById('designer-show-filetree').checked = false;
|
||||||
|
|
||||||
|
// Set height and colors for Claude
|
||||||
|
const heightSlider = document.getElementById('designer-height');
|
||||||
|
const heightValue = document.getElementById('height-value');
|
||||||
|
if (heightSlider) {
|
||||||
|
heightSlider.value = '350';
|
||||||
|
if (heightValue) {
|
||||||
|
heightValue.textContent = '350';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Claude orange color scheme
|
||||||
|
document.getElementById('designer-light-color').value = '#f97316';
|
||||||
|
document.getElementById('designer-light-color-text').value = '#f97316';
|
||||||
|
document.getElementById('designer-dark-color').value = '#fb923c';
|
||||||
|
document.getElementById('designer-dark-color-text').value = '#fb923c';
|
||||||
|
|
||||||
|
// Auto theme for Claude
|
||||||
|
this.config.themeMode = 'auto';
|
||||||
|
this.updateThemeModeButtons();
|
||||||
|
|
||||||
|
// Clear diff view
|
||||||
|
document.getElementById('designer-show-diff').checked = false;
|
||||||
|
document.getElementById('diff-fields').classList.add('hidden');
|
||||||
|
document.getElementById('designer-flash-button').value = 'none';
|
||||||
|
|
||||||
|
// Update config from form
|
||||||
|
this.updateConfigFromForm();
|
||||||
|
|
||||||
|
this.showNotification('Claude example loaded!');
|
||||||
|
}
|
||||||
|
|
||||||
|
loadImageAnalysisExample() {
|
||||||
|
// Image analysis example
|
||||||
|
document.getElementById('designer-prompt').value =
|
||||||
|
`Analyze these UI screenshots and provide detailed feedback on:
|
||||||
|
- Visual hierarchy and layout
|
||||||
|
- Color scheme and contrast
|
||||||
|
- Typography choices
|
||||||
|
- Accessibility concerns
|
||||||
|
- Mobile responsiveness issues`;
|
||||||
|
|
||||||
|
document.getElementById('designer-context').value = '#Homepage Desktop.png, #Homepage Mobile.png, #Dashboard View.jpg';
|
||||||
|
document.getElementById('designer-filetree').value = '';
|
||||||
|
|
||||||
|
// Image analysis settings
|
||||||
|
document.getElementById('designer-model').value = 'GPT 4.1';
|
||||||
|
document.getElementById('designer-mode-select').value = 'chat';
|
||||||
|
document.getElementById('designer-thinking').checked = false;
|
||||||
|
document.getElementById('designer-max').checked = false;
|
||||||
|
document.getElementById('designer-show-filetree').checked = false;
|
||||||
|
|
||||||
|
// Set height and colors
|
||||||
|
const heightSlider = document.getElementById('designer-height');
|
||||||
|
const heightValue = document.getElementById('height-value');
|
||||||
|
if (heightSlider) {
|
||||||
|
heightSlider.value = '400';
|
||||||
|
if (heightValue) {
|
||||||
|
heightValue.textContent = '400';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pink/purple color scheme for design
|
||||||
|
document.getElementById('designer-light-color').value = '#ec4899';
|
||||||
|
document.getElementById('designer-light-color-text').value = '#ec4899';
|
||||||
|
document.getElementById('designer-dark-color').value = '#f472b6';
|
||||||
|
document.getElementById('designer-dark-color-text').value = '#f472b6';
|
||||||
|
|
||||||
|
// Light theme
|
||||||
|
this.config.themeMode = 'light';
|
||||||
|
this.updateThemeModeButtons();
|
||||||
|
|
||||||
|
// Clear diff view
|
||||||
|
document.getElementById('designer-show-diff').checked = false;
|
||||||
|
document.getElementById('diff-fields').classList.add('hidden');
|
||||||
|
document.getElementById('designer-flash-button').value = 'none';
|
||||||
|
|
||||||
|
// Update config from form
|
||||||
|
this.updateConfigFromForm();
|
||||||
|
|
||||||
|
this.showNotification('Image analysis example loaded!');
|
||||||
|
}
|
||||||
|
|
||||||
|
loadAPIDesignExample() {
|
||||||
|
// API design example
|
||||||
|
document.getElementById('designer-prompt').value =
|
||||||
|
`Design a RESTful API for a task management system with:
|
||||||
|
- User authentication
|
||||||
|
- Project and task CRUD operations
|
||||||
|
- Team collaboration features
|
||||||
|
- Real-time notifications
|
||||||
|
|
||||||
|
Include endpoint definitions, request/response schemas, and error handling patterns.`;
|
||||||
|
|
||||||
|
document.getElementById('designer-context').value = '@Web, openapi.yaml';
|
||||||
|
document.getElementById('designer-filetree').value =
|
||||||
|
`api/
|
||||||
|
api/v1/
|
||||||
|
api/v1/users/
|
||||||
|
api/v1/projects/
|
||||||
|
api/v1/tasks/
|
||||||
|
docs/openapi.yaml*`;
|
||||||
|
|
||||||
|
// API design settings
|
||||||
|
document.getElementById('designer-model').value = 'Claude 4 Opus';
|
||||||
|
document.getElementById('designer-mode-select').value = 'manual';
|
||||||
|
document.getElementById('designer-thinking').checked = true;
|
||||||
|
document.getElementById('designer-max').checked = false;
|
||||||
|
document.getElementById('designer-show-filetree').checked = true;
|
||||||
|
|
||||||
|
// Set height and colors
|
||||||
|
const heightSlider = document.getElementById('designer-height');
|
||||||
|
const heightValue = document.getElementById('height-value');
|
||||||
|
if (heightSlider) {
|
||||||
|
heightSlider.value = '500';
|
||||||
|
if (heightValue) {
|
||||||
|
heightValue.textContent = '500';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blue color scheme for API
|
||||||
|
document.getElementById('designer-light-color').value = '#3b82f6';
|
||||||
|
document.getElementById('designer-light-color-text').value = '#3b82f6';
|
||||||
|
document.getElementById('designer-dark-color').value = '#60a5fa';
|
||||||
|
document.getElementById('designer-dark-color-text').value = '#60a5fa';
|
||||||
|
|
||||||
|
// Dark theme for technical
|
||||||
|
this.config.themeMode = 'dark';
|
||||||
|
this.updateThemeModeButtons();
|
||||||
|
|
||||||
|
// Clear diff view
|
||||||
|
document.getElementById('designer-show-diff').checked = false;
|
||||||
|
document.getElementById('diff-fields').classList.add('hidden');
|
||||||
|
document.getElementById('designer-flash-button').value = 'none';
|
||||||
|
|
||||||
|
// Update config from form
|
||||||
|
this.updateConfigFromForm();
|
||||||
|
|
||||||
|
this.showNotification('API design example loaded!');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +249,7 @@ body.dark-mode .designer-panel {
|
|||||||
|
|
||||||
/* Adjust the scrollable content area */
|
/* Adjust the scrollable content area */
|
||||||
.designer-panel > .flex-1 {
|
.designer-panel > .flex-1 {
|
||||||
padding-top: calc(var(--header-height) + 1rem);
|
padding-top: calc(var(--header-height));
|
||||||
height: 100%;
|
height: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user