@@ -5,10 +5,10 @@ import { Send, ArrowRight } from 'lucide-react';
55import SchemaCanvasViewer from './SchemaCanvasViewer' ;
66
77const SUGGESTIONS = [
8- { label : '🛒 E-commerce store ' , prompt : 'Create an e-commerce platform with products, categories, orders, and customer reviews' } ,
9- { label : '📋 Project management ' , prompt : 'Build a project management tool with workspaces, tasks, milestones, and time tracking ' } ,
10- { label : '📝 Blog platform ' , prompt : 'Design a blog with posts, authors, tags, comments , and draft management ' } ,
11- { label : '🎓 Learning platform ' , prompt : 'Create a learning platform with courses, modules, lessons, quizzes , and student enrollments ' } ,
8+ { label : 'E-commerce Platform ' , prompt : 'Create an e-commerce platform with products, categories, orders, customers, and product reviews' } ,
9+ { label : 'Project Management SaaS ' , prompt : 'Build a project management system with workspaces, projects, tasks, milestones, and team members ' } ,
10+ { label : 'Subscription Billing API ' , prompt : 'Design a subscription service with plans, subscriptions, invoices, payment methods , and usage logs ' } ,
11+ { label : 'Content Management (CMS) ' , prompt : 'Design a headless CMS with articles, authors, categories, media assets , and publishing revisions ' } ,
1212] ;
1313
1414const createMsg = ( role , content ) => ( {
@@ -19,7 +19,7 @@ const createMsg = (role, content) => ({
1919
2020export default function CollectionCreatorAgent ( { projectId, onInsertAll } ) {
2121 const [ messages , setMessages ] = useState ( [
22- createMsg ( 'assistant' , "Hi! Tell me what you're building — for example: 'a food delivery app' or 'a SaaS project management tool' — and I'll design a MongoDB schema for you." )
22+ createMsg ( 'assistant' , "Describe what you're building — for example: a multi-tenant SaaS, an e-commerce platform, or a workflow tool — and I will design a production-ready MongoDB schema for you." )
2323 ] ) ;
2424 const [ aiStatus , setAiStatus ] = useState ( 'idle' ) ; // 'idle' | 'loading' | 'error'
2525 const [ schema , setSchema ] = useState ( null ) ;
@@ -106,7 +106,7 @@ export default function CollectionCreatorAgent({ projectId, onInsertAll }) {
106106 try {
107107 await api . delete ( `/api/projects/${ projectId } /ai/collection-creator/session` ) ;
108108 setMessages ( [
109- createMsg ( 'assistant' , "Hi! Tell me what you're building — for example: 'a food delivery app' or 'a SaaS project management tool' — and I'll design a MongoDB schema for you." )
109+ createMsg ( 'assistant' , "Describe what you're building — for example: a multi-tenant SaaS, an e-commerce platform, or a workflow tool — and I will design a production-ready MongoDB schema for you." )
110110 ] ) ;
111111 setSchema ( null ) ;
112112 setInsertResults ( null ) ;
@@ -214,37 +214,30 @@ export default function CollectionCreatorAgent({ projectId, onInsertAll }) {
214214 } ;
215215
216216 return (
217- < div className = "flex flex-col lg:flex-row gap-8 h-[calc(100vh-170px)] min-h-[580px] font-sans" >
217+ < div className = "flex flex-col lg:flex-row gap-5 h-full w-full font-sans overflow-hidden " >
218218
219- { /* Open Chat Stream & Floating Composer - Left */ }
220- < div className = "flex flex-col flex-1 h-full relative" style = { { display : 'flex' , flexDirection : 'column' } } >
219+ { /* Open Chat Stream & Pinned Composer - Left */ }
220+ < div className = "flex flex-col flex-1 h-full min-w-0 overflow-hidden relative" >
221221
222- { /* Messages Stream (No container box ) */ }
222+ { /* Messages Stream (Only this scrolls ) */ }
223223 < div
224- className = "flex-1 overflow-y-auto custom-scrollbar"
225- style = { {
226- paddingRight : '1rem' ,
227- paddingBottom : '1rem' ,
228- display : 'flex' ,
229- flexDirection : 'column' ,
230- gap : '1.25rem'
231- } }
224+ className = "flex-1 overflow-y-auto custom-scrollbar pr-2 flex flex-col gap-3 min-h-0"
232225 >
233226 { messages . map ( ( msg ) => (
234227 < div key = { msg . id } className = { `flex ${ msg . role === 'user' ? 'justify-end' : 'justify-start' } ` } >
235228 < div
236229 style = { {
237230 maxWidth : '85%' ,
238- padding : '14px 20px ' ,
239- fontSize : '0.9rem ' ,
240- lineHeight : '1.6 ' ,
241- borderRadius : '18px ' ,
242- borderBottomRightRadius : msg . role === 'user' ? '4px ' : '18px ' ,
243- borderBottomLeftRadius : msg . role === 'assistant' ? '4px ' : '18px ' ,
231+ padding : '10px 16px ' ,
232+ fontSize : '0.85rem ' ,
233+ lineHeight : '1.55 ' ,
234+ borderRadius : '14px ' ,
235+ borderBottomRightRadius : msg . role === 'user' ? '3px ' : '14px ' ,
236+ borderBottomLeftRadius : msg . role === 'assistant' ? '3px ' : '14px ' ,
244237 backgroundColor : msg . role === 'user' ? 'var(--color-primary)' : 'var(--color-bg-card)' ,
245238 color : msg . role === 'user' ? '#000' : 'var(--color-text-main)' ,
246239 border : msg . role === 'assistant' ? '1px solid var(--color-border)' : 'none' ,
247- boxShadow : msg . role === 'assistant' ? '0 2px 10px rgba(0,0,0,0.06 )' : '0 4px 14px rgba(62,207,142,0.25 )' ,
240+ boxShadow : msg . role === 'assistant' ? '0 1px 4px rgba(0,0,0,0.05 )' : '0 2px 8px rgba(62,207,142,0.2 )' ,
248241 whiteSpace : 'pre-wrap'
249242 } }
250243 >
@@ -255,46 +248,21 @@ export default function CollectionCreatorAgent({ projectId, onInsertAll }) {
255248
256249 { /* Quick Start Suggestions on empty chat */ }
257250 { messages . length <= 1 && ! schema && (
258- < div style = { { marginTop : '0.5rem' , display : ' flex' , flexDirection : 'column' , gap : '8px' } } >
259- < span style = { { fontSize : '0.75rem' , fontWeight : 600 , color : ' var(--color-text-muted)' , textTransform : ' uppercase' , letterSpacing : '0.05em' , paddingLeft : '4px' } } >
251+ < div className = "mt-1 flex flex-col gap-2" >
252+ < span className = "text-[10px] font-semibold text-[ var(--color-text-muted)] uppercase tracking-wider pl-1" >
260253 Quick Start Ideas
261254 </ span >
262- < div style = { { display : ' grid' , gridTemplateColumns : 'repeat(auto-fit, minmax(220px, 1fr))' , gap : '8px' } } >
255+ < div className = "grid grid-cols-1 sm:grid-cols-2 gap-2" >
263256 { SUGGESTIONS . map ( ( s , i ) => (
264257 < button
265258 key = { i }
266259 type = "button"
267260 onClick = { ( ) => sendMessage ( null , s . prompt ) }
268261 disabled = { aiStatus === 'loading' || iterationsLeft === 0 }
269- style = { {
270- textAlign : 'left' ,
271- padding : '10px 14px' ,
272- backgroundColor : 'var(--color-bg-card)' ,
273- border : '1px solid var(--color-border)' ,
274- borderRadius : '12px' ,
275- fontSize : '0.825rem' ,
276- color : 'var(--color-text-main)' ,
277- cursor : ( aiStatus === 'loading' || iterationsLeft === 0 ) ? 'not-allowed' : 'pointer' ,
278- opacity : ( aiStatus === 'loading' || iterationsLeft === 0 ) ? 0.45 : 1 ,
279- transition : 'all 0.2s ease' ,
280- display : 'flex' ,
281- alignItems : 'center' ,
282- justifyContent : 'space-between' ,
283- gap : '8px'
284- } }
285- onMouseEnter = { ( e ) => {
286- if ( aiStatus !== 'loading' && iterationsLeft !== 0 ) {
287- e . currentTarget . style . borderColor = 'var(--color-primary)' ;
288- e . currentTarget . style . transform = 'translateY(-1px)' ;
289- }
290- } }
291- onMouseLeave = { ( e ) => {
292- e . currentTarget . style . borderColor = 'var(--color-border)' ;
293- e . currentTarget . style . transform = 'translateY(0)' ;
294- } }
262+ className = "text-left p-2.5 px-3 bg-[var(--color-bg-card)] border border-[var(--color-border)] hover:border-[var(--color-primary)] rounded-lg text-xs text-[var(--color-text-main)] flex items-center justify-between gap-2 transition-all cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed"
295263 >
296- < span > { s . label } </ span >
297- < ArrowRight size = { 13 } style = { { opacity : 0.6 , flexShrink : 0 } } />
264+ < span className = "truncate" > { s . label } </ span >
265+ < ArrowRight size = { 12 } className = " opacity-50 shrink-0" />
298266 </ button >
299267 ) ) }
300268 </ div >
@@ -303,20 +271,9 @@ export default function CollectionCreatorAgent({ projectId, onInsertAll }) {
303271
304272 { aiStatus === 'loading' && (
305273 < div className = "flex justify-start" >
306- < div
307- style = { {
308- backgroundColor : 'var(--color-bg-card)' ,
309- padding : '12px 20px' ,
310- borderRadius : '18px' ,
311- borderBottomLeftRadius : '4px' ,
312- border : '1px solid var(--color-border)' ,
313- display : 'flex' ,
314- alignItems : 'center' ,
315- gap : '10px'
316- } }
317- >
318- < div className = "spinner-small" style = { { width : '14px' , height : '14px' , borderTopColor : 'var(--color-primary)' } } > </ div >
319- < span style = { { fontSize : '0.85rem' , color : 'var(--color-text-muted)' , fontWeight : 500 } } >
274+ < div className = "bg-[var(--color-bg-card)] p-2.5 px-4 rounded-xl rounded-bl-sm border border-[var(--color-border)] flex items-center gap-2.5 shadow-sm" >
275+ < div className = "spinner-small w-3.5 h-3.5 border-t-[var(--color-primary)]" > </ div >
276+ < span className = "text-xs text-[var(--color-text-muted)] font-medium" >
320277 AI is designing your schema...
321278 </ span >
322279 </ div >
@@ -325,67 +282,30 @@ export default function CollectionCreatorAgent({ projectId, onInsertAll }) {
325282 < div ref = { messagesEndRef } />
326283 </ div >
327284
328- { /* Floating Bottom Composer */ }
329- < div style = { { marginTop : ' auto' , paddingTop : '12px' , flexShrink : 0 } } >
285+ { /* Pinned Bottom Composer */ }
286+ < div className = "mt- auto pt-2 flex-shrink-0" >
330287 < div
331- style = { {
332- position : 'relative' ,
333- display : 'flex' ,
334- alignItems : 'flex-end' ,
335- backgroundColor : 'var(--color-bg-card)' ,
336- border : '1px solid var(--color-border)' ,
337- borderRadius : '20px' ,
338- padding : '10px 14px 10px 20px' ,
339- boxShadow : '0 8px 32px rgba(0,0,0,0.25)' ,
340- transition : 'border-color 0.2s ease, box-shadow 0.2s ease'
341- } }
288+ className = "relative flex items-end bg-[var(--color-bg-card)] border border-[var(--color-border)] rounded-xl p-2 px-3 shadow-lg transition-all focus-within:border-[var(--color-primary)]"
342289 >
343290 < textarea
344291 ref = { textareaRef }
345292 value = { inputValue }
346293 onChange = { ( e ) => setInputValue ( e . target . value ) }
347294 onKeyDown = { handleKeyDown }
348295 disabled = { aiStatus === 'loading' || ( iterationsLeft === 0 ) }
349- placeholder = { iterationsLeft === 0 ? "Turn limit reached. Add Groq key in Settings." : "Describe your app (e.g. e-commerce, project management, todo app ...)" }
296+ placeholder = { iterationsLeft === 0 ? "Turn limit reached. Add Groq key in Settings." : "Describe your app (e.g. e-commerce store, booking system, CRM ...)" }
350297 aria-label = "Message the schema assistant"
351298 rows = { 1 }
352- style = { {
353- width : '100%' ,
354- background : 'transparent' ,
355- border : 'none' ,
356- outline : 'none' ,
357- color : 'var(--color-text-main)' ,
358- fontSize : '0.9rem' ,
359- lineHeight : '1.5' ,
360- resize : 'none' ,
361- maxHeight : '130px' ,
362- minHeight : '26px' ,
363- padding : '4px 0'
364- } }
299+ className = "w-full bg-transparent border-0 outline-none text-[var(--color-text-main)] text-xs leading-relaxed resize-none max-h-[100px] min-h-[24px] py-1 placeholder:text-[var(--color-text-muted)]"
365300 />
366301 < button
367302 type = "button"
368303 onClick = { sendMessage }
369304 disabled = { ! inputValue . trim ( ) || aiStatus === 'loading' || ( iterationsLeft === 0 ) }
370- style = { {
371- display : 'flex' ,
372- alignItems : 'center' ,
373- justifyContent : 'center' ,
374- width : '36px' ,
375- height : '36px' ,
376- borderRadius : '50%' ,
377- backgroundColor : ( inputValue . trim ( ) && aiStatus !== 'loading' && iterationsLeft !== 0 ) ? 'var(--color-primary)' : 'var(--color-bg-input)' ,
378- color : ( inputValue . trim ( ) && aiStatus !== 'loading' && iterationsLeft !== 0 ) ? '#000' : 'var(--color-text-muted)' ,
379- border : '1px solid var(--color-border)' ,
380- cursor : ( inputValue . trim ( ) && aiStatus !== 'loading' && iterationsLeft !== 0 ) ? 'pointer' : 'default' ,
381- opacity : ( ! inputValue . trim ( ) || aiStatus === 'loading' || iterationsLeft === 0 ) ? 0.4 : 1 ,
382- transition : 'all 0.2s ease' ,
383- flexShrink : 0 ,
384- marginLeft : '10px'
385- } }
305+ className = "flex items-center justify-center w-7 h-7 rounded-lg bg-[var(--color-primary)] text-black border-0 cursor-pointer disabled:opacity-35 disabled:cursor-not-allowed transition-all shrink-0 ml-2"
386306 title = "Send message (Enter)"
387307 >
388- < Send size = { 15 } />
308+ < Send size = { 13 } />
389309 </ button >
390310 </ div >
391311 { getIterationsBadge ( ) }
0 commit comments