Skip to content

Commit 4792e81

Browse files
committed
fix(dashboard): resolve layout clipping, fix double padding in MainLayout, expand canvas node separation and spacing across all creator elements
1 parent 65cb7c3 commit 4792e81

6 files changed

Lines changed: 80 additions & 84 deletions

File tree

‎apps/web-dashboard/src/components/CollectionCreatorAgent.jsx‎

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -214,30 +214,30 @@ export default function CollectionCreatorAgent({ projectId, onInsertAll }) {
214214
};
215215

216216
return (
217-
<div className="flex flex-col lg:flex-row gap-5 h-full w-full font-sans overflow-hidden">
217+
<div className="flex flex-col lg:flex-row gap-8 h-full w-full font-sans overflow-hidden">
218218

219219
{/* Open Chat Stream & Pinned Composer - Left */}
220220
<div className="flex flex-col flex-1 h-full min-w-0 overflow-hidden relative">
221221

222222
{/* Messages Stream (Only this scrolls) */}
223223
<div
224-
className="flex-1 overflow-y-auto custom-scrollbar pr-2 flex flex-col gap-3 min-h-0"
224+
className="flex-1 overflow-y-auto custom-scrollbar pr-3 flex flex-col gap-4 min-h-0"
225225
>
226226
{messages.map((msg) => (
227227
<div key={msg.id} className={`flex ${msg.role === 'user' ? 'justify-end' : 'justify-start'}`}>
228228
<div
229229
style={{
230230
maxWidth: '85%',
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',
231+
padding: '12px 18px',
232+
fontSize: '0.875rem',
233+
lineHeight: '1.6',
234+
borderRadius: '16px',
235+
borderBottomRightRadius: msg.role === 'user' ? '4px' : '16px',
236+
borderBottomLeftRadius: msg.role === 'assistant' ? '4px' : '16px',
237237
backgroundColor: msg.role === 'user' ? 'var(--color-primary)' : 'var(--color-bg-card)',
238238
color: msg.role === 'user' ? '#000' : 'var(--color-text-main)',
239239
border: msg.role === 'assistant' ? '1px solid var(--color-border)' : 'none',
240-
boxShadow: msg.role === 'assistant' ? '0 1px 4px rgba(0,0,0,0.05)' : '0 2px 8px rgba(62,207,142,0.2)',
240+
boxShadow: msg.role === 'assistant' ? '0 2px 8px rgba(0,0,0,0.06)' : '0 3px 12px rgba(62,207,142,0.22)',
241241
whiteSpace: 'pre-wrap'
242242
}}
243243
>
@@ -248,21 +248,21 @@ export default function CollectionCreatorAgent({ projectId, onInsertAll }) {
248248

249249
{/* Quick Start Suggestions on empty chat */}
250250
{messages.length <= 1 && !schema && (
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">
251+
<div className="mt-2 flex flex-col gap-2.5">
252+
<span className="text-[11px] font-semibold text-[var(--color-text-muted)] uppercase tracking-wider pl-1">
253253
Quick Start Ideas
254254
</span>
255-
<div className="grid grid-cols-1 sm:grid-cols-2 gap-2">
255+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-2.5">
256256
{SUGGESTIONS.map((s, i) => (
257257
<button
258258
key={i}
259259
type="button"
260260
onClick={() => sendMessage(null, s.prompt)}
261261
disabled={aiStatus === 'loading' || iterationsLeft === 0}
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"
262+
className="text-left p-3 px-3.5 bg-[var(--color-bg-card)] border border-[var(--color-border)] hover:border-[var(--color-primary)] rounded-xl text-xs font-medium text-[var(--color-text-main)] flex items-center justify-between gap-3 transition-all cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed shadow-sm hover:shadow"
263263
>
264264
<span className="truncate">{s.label}</span>
265-
<ArrowRight size={12} className="opacity-50 shrink-0" />
265+
<ArrowRight size={13} className="opacity-50 shrink-0" />
266266
</button>
267267
))}
268268
</div>
@@ -271,8 +271,8 @@ export default function CollectionCreatorAgent({ projectId, onInsertAll }) {
271271

272272
{aiStatus === 'loading' && (
273273
<div className="flex justify-start">
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>
274+
<div className="bg-[var(--color-bg-card)] p-3 px-4 rounded-xl rounded-bl-sm border border-[var(--color-border)] flex items-center gap-3 shadow-sm">
275+
<div className="spinner-small w-4 h-4 border-t-[var(--color-primary)]"></div>
276276
<span className="text-xs text-[var(--color-text-muted)] font-medium">
277277
AI is designing your schema...
278278
</span>
@@ -283,9 +283,9 @@ export default function CollectionCreatorAgent({ projectId, onInsertAll }) {
283283
</div>
284284

285285
{/* Pinned Bottom Composer */}
286-
<div className="mt-auto pt-2 flex-shrink-0">
286+
<div className="mt-auto pt-3 flex-shrink-0">
287287
<div
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)]"
288+
className="relative flex items-end bg-[var(--color-bg-card)] border border-[var(--color-border)] rounded-xl p-2.5 px-4 shadow-lg transition-all focus-within:border-[var(--color-primary)] focus-within:ring-1 focus-within:ring-[var(--color-primary)]/30"
289289
>
290290
<textarea
291291
ref={textareaRef}
@@ -296,16 +296,16 @@ export default function CollectionCreatorAgent({ projectId, onInsertAll }) {
296296
placeholder={iterationsLeft === 0 ? "Turn limit reached. Add Groq key in Settings." : "Describe your app (e.g. e-commerce store, booking system, CRM...)"}
297297
aria-label="Message the schema assistant"
298298
rows={1}
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)]"
299+
className="w-full bg-transparent border-0 outline-none text-[var(--color-text-main)] text-sm leading-relaxed resize-none max-h-[110px] min-h-[26px] py-1 placeholder:text-[var(--color-text-muted)]"
300300
/>
301301
<button
302302
type="button"
303303
onClick={sendMessage}
304304
disabled={!inputValue.trim() || aiStatus === 'loading' || (iterationsLeft === 0)}
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"
305+
className="flex items-center justify-center w-8 h-8 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.5 font-semibold"
306306
title="Send message (Enter)"
307307
>
308-
<Send size={13} />
308+
<Send size={14} />
309309
</button>
310310
</div>
311311
{getIterationsBadge()}

‎apps/web-dashboard/src/components/Layout/MainLayout.jsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ function MainLayout({ children }) {
7070
className="content-wrapper"
7171
style={{
7272
marginTop: 0,
73-
padding: isProjectRoute && location.pathname.includes('/database') ? 0 : undefined
73+
padding: isProjectRoute && (location.pathname.includes('/database') || location.pathname.includes('/create-collection')) ? 0 : undefined
7474
}}
7575
>
7676
{children}

‎apps/web-dashboard/src/components/SchemaCanvas/CollectionNode.jsx‎

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ import { Badge } from '../ui/badge';
55

66
const getTypeIcon = (type) => {
77
switch (type) {
8-
case 'String': return <Type size={12} className="text-emerald-500" />;
9-
case 'Number': return <Hash size={12} className="text-blue-500" />;
10-
case 'Boolean': return <ToggleLeft size={12} className="text-amber-500" />;
11-
case 'Date': return <Calendar size={12} className="text-purple-500" />;
12-
case 'Ref': return <Link2 size={12} className="text-cyan-500" />;
13-
case 'Object': return <Layers size={12} className="text-orange-500" />;
14-
case 'Array': return <Brackets size={12} className="text-pink-500" />;
15-
default: return <Type size={12} className="text-gray-400" />;
8+
case 'String': return <Type size={12} className="text-emerald-500 shrink-0" />;
9+
case 'Number': return <Hash size={12} className="text-blue-500 shrink-0" />;
10+
case 'Boolean': return <ToggleLeft size={12} className="text-amber-500 shrink-0" />;
11+
case 'Date': return <Calendar size={12} className="text-purple-500 shrink-0" />;
12+
case 'Ref': return <Link2 size={12} className="text-cyan-500 shrink-0" />;
13+
case 'Object': return <Layers size={12} className="text-orange-500 shrink-0" />;
14+
case 'Array': return <Brackets size={12} className="text-pink-500 shrink-0" />;
15+
default: return <Type size={12} className="text-gray-400 shrink-0" />;
1616
}
1717
};
1818

@@ -34,10 +34,10 @@ function CollectionNode({ data, selected }) {
3434

3535
return (
3636
<div
37-
className={`min-w-[270px] max-w-[340px] rounded-xl border bg-[var(--color-bg-card)] shadow-xl transition-all duration-150 relative select-none ${
37+
className={`min-w-[290px] max-w-[360px] rounded-xl border bg-[var(--color-bg-card)] shadow-2xl transition-all duration-150 relative select-none ${
3838
selected
39-
? 'border-[var(--color-primary)] ring-2 ring-[var(--color-primary)]/20 shadow-2xl'
40-
: 'border-[var(--color-border)] hover:border-[var(--color-text-muted)]'
39+
? 'border-[var(--color-primary)] ring-2 ring-[var(--color-primary)]/25 shadow-2xl'
40+
: 'border-[var(--color-border)] hover:border-[var(--color-border-hover)]'
4141
}`}
4242
>
4343
{/* Target Handle (Left) */}
@@ -57,36 +57,36 @@ function CollectionNode({ data, selected }) {
5757
/>
5858

5959
{/* Node Header */}
60-
<div className="flex items-center justify-between border-b border-[var(--color-border)] bg-[var(--color-bg-input)] px-4 py-2.5 rounded-t-xl">
61-
<div className="flex items-center gap-2 min-w-0">
62-
<div className="w-5 h-5 rounded flex items-center justify-center bg-[var(--color-primary)]/15 text-[var(--color-primary)]">
63-
<Database size={13} />
60+
<div className="flex items-center justify-between border-b border-[var(--color-border)] bg-[var(--color-bg-input)] px-4 py-3 rounded-t-xl">
61+
<div className="flex items-center gap-2.5 min-w-0">
62+
<div className="w-6 h-6 rounded-md flex items-center justify-center bg-[var(--color-primary)]/15 text-[var(--color-primary)] shrink-0">
63+
<Database size={14} />
6464
</div>
65-
<span className="font-semibold text-xs text-[var(--color-text-main)] truncate font-mono">
65+
<span className="font-bold text-xs text-[var(--color-text-main)] truncate font-mono">
6666
{name}
6767
</span>
6868
</div>
6969
<div className="flex items-center gap-2 shrink-0">
7070
{isLocked && (
71-
<Badge variant="warning" className="text-[9px] px-1.5 py-0 h-4">
71+
<Badge variant="warning" className="text-[10px] px-2 py-0.5 h-5 font-semibold">
7272
Auth
7373
</Badge>
7474
)}
75-
<span className="text-[10px] text-[var(--color-text-muted)] font-mono">
75+
<span className="text-[11px] text-[var(--color-text-muted)] font-mono font-medium">
7676
{fields.length} fields
7777
</span>
7878
</div>
7979
</div>
8080

8181
{/* Fields List */}
82-
<div className="p-2 divide-y divide-[var(--color-border)]/50 max-h-[300px] overflow-y-auto custom-scrollbar">
82+
<div className="p-2.5 divide-y divide-[var(--color-border)]/50 max-h-[320px] overflow-y-auto custom-scrollbar">
8383
{/* Default _id field */}
84-
<div className="flex items-center justify-between py-1.5 px-2 text-xs text-[var(--color-text-muted)]">
85-
<div className="flex items-center gap-2 min-w-0">
86-
<Key size={12} className="text-amber-500 shrink-0" />
84+
<div className="flex items-center justify-between py-2 px-3 text-xs text-[var(--color-text-muted)] rounded-md">
85+
<div className="flex items-center gap-2.5 min-w-0">
86+
<Key size={13} className="text-amber-500 shrink-0" />
8787
<span className="font-mono text-xs text-[var(--color-text-main)] font-semibold truncate">_id</span>
8888
</div>
89-
<Badge variant="outline" className="text-[9px] px-1.5 py-0 h-4 font-mono">
89+
<Badge variant="outline" className="text-[10px] px-2 py-0.5 h-5 font-mono">
9090
ObjectId (PK)
9191
</Badge>
9292
</div>
@@ -97,23 +97,23 @@ function CollectionNode({ data, selected }) {
9797
return (
9898
<div
9999
key={field.key}
100-
className="relative flex items-center justify-between py-1.5 px-2 text-xs hover:bg-[var(--color-surface-hover)] rounded-md group transition-colors"
100+
className="relative flex items-center justify-between py-2 px-3 text-xs hover:bg-[var(--color-surface-hover)] rounded-md group transition-colors my-0.5"
101101
>
102102
<div className="flex items-center gap-2 min-w-0 flex-1">
103103
{getTypeIcon(field.type)}
104-
<span className="font-mono text-xs text-[var(--color-text-main)] truncate">
104+
<span className="font-mono text-xs text-[var(--color-text-main)] font-medium truncate">
105105
{field.key}
106106
</span>
107107
{field.required && (
108108
<span className="text-red-400 font-bold text-xs" title="Required field">*</span>
109109
)}
110110
{field.unique && (
111-
<span className="text-[9px] text-amber-500 font-mono" title="Unique constraint">[U]</span>
111+
<span className="text-[10px] text-amber-500 font-mono font-bold" title="Unique constraint">[U]</span>
112112
)}
113113
</div>
114114

115-
<div className="flex items-center gap-1.5 shrink-0 ml-2">
116-
<Badge variant={getTypeVariant(field.type)} className="text-[9px] px-1.5 py-0 h-4 font-mono">
115+
<div className="flex items-center gap-2 shrink-0 ml-2">
116+
<Badge variant={getTypeVariant(field.type)} className="text-[10px] px-2 py-0.5 h-5 font-mono">
117117
{field.type === 'Ref' && field.ref
118118
? `Ref → ${field.ref}`
119119
: field.type === 'Array' && field.items?.type

‎apps/web-dashboard/src/components/SchemaCanvas/SchemaCanvas.jsx‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,23 @@ export default function SchemaCanvas({ collections = [], isAiAssisted = false })
2727
let relationCount = 0;
2828

2929
const COLS = collections.length > 3 ? 3 : 2;
30-
const X_GAP = 420;
31-
const Y_GAP = 360;
30+
const X_GAP = 480;
31+
const Y_GAP = 420;
3232

3333
// Index map for smart routing
3434
const colIndexMap = {};
3535
collections.forEach((col, idx) => {
3636
colIndexMap[col.name] = {
37-
colX: (idx % COLS) * X_GAP + 50,
38-
colY: Math.floor(idx / COLS) * Y_GAP + 50,
37+
colX: (idx % COLS) * X_GAP + 60,
38+
colY: Math.floor(idx / COLS) * Y_GAP + 60,
3939
index: idx,
4040
col: idx % COLS,
4141
row: Math.floor(idx / COLS)
4242
};
4343
});
4444

4545
collections.forEach((col, idx) => {
46-
const pos = colIndexMap[col.name] || { colX: (idx % COLS) * X_GAP + 50, colY: Math.floor(idx / COLS) * Y_GAP + 50 };
46+
const pos = colIndexMap[col.name] || { colX: (idx % COLS) * X_GAP + 60, colY: Math.floor(idx / COLS) * Y_GAP + 60 };
4747
const fields = col.model || col.fields || [];
4848
fieldCount += fields.length;
4949

@@ -78,8 +78,8 @@ export default function SchemaCanvas({ collections = [], isAiAssisted = false })
7878
type: 'smoothstep',
7979
animated: true,
8080
pathOptions: {
81-
borderRadius: 16,
82-
offset: 24,
81+
borderRadius: 20,
82+
offset: 32,
8383
},
8484
label: `${field.key} → ${targetRef}`,
8585
labelStyle: { fill: 'var(--color-text-main)', fontSize: 10, fontFamily: 'monospace', fontWeight: 600 },

0 commit comments

Comments
 (0)