Skip to content

Commit 28c95df

Browse files
committed
feat: enhance ObjectDataForm with improved styling and button components
1 parent 245cfc4 commit 28c95df

2 files changed

Lines changed: 151 additions & 158 deletions

File tree

examples/app-react-crud/src/App.tsx

Lines changed: 68 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import { useState, useEffect } from 'react';
1111
import { ObjectStackClient } from '@objectstack/client';
12+
import { Database } from 'lucide-react';
1213
import { MetadataExplorer } from './components/MetadataExplorer';
1314
import { ObjectDataTable } from './components/ObjectDataTable';
1415
import { ObjectDataForm } from './components/ObjectDataForm';
@@ -23,6 +24,7 @@ export function App() {
2324
const [selectedObject, setSelectedObject] = useState<string | null>('todo_task');
2425
const [view, setView] = useState<'list' | 'form'>('list');
2526
const [editingRecord, setEditingRecord] = useState<any>(null); // null = create new
27+
const [refreshKey, setRefreshKey] = useState(0);
2628

2729
useEffect(() => {
2830
initializeClient();
@@ -60,108 +62,94 @@ export function App() {
6062
const handleFormSuccess = () => {
6163
setView('list');
6264
setEditingRecord(null);
63-
// Table will reload when switching back to list implicitly if we force refresh?
64-
// Actually ObjectDataTable mounts again or we can trigger refresh.
65-
// For simplicity, remounting works or we can add a refresh trigger key.
65+
setRefreshKey(k => k + 1);
6666
};
6767

6868
if (!connected || !client) {
6969
return (
70-
<div className="min-h-screen flex items-center justify-center bg-gray-100">
71-
<div className="text-center">
72-
<h2 className="text-xl font-bold text-gray-700">Connecting to Platform...</h2>
73-
{error && <p className="text-red-500 mt-2">{error}</p>}
70+
<div className="min-h-screen flex items-center justify-center bg-background">
71+
<div className="text-center space-y-4">
72+
<h2 className="text-xl font-bold text-foreground">Connecting to Platform...</h2>
73+
{error && <p className="text-destructive font-medium">{error}</p>}
7474
</div>
7575
</div>
7676
);
7777
}
7878

7979
return (
80-
<div className="min-h-screen bg-gray-100 font-sans flex flex-col">
80+
<div className="min-h-screen bg-background font-sans flex flex-col text-foreground">
8181
{/* Top Header */}
82-
<header className="bg-foreground text-background shadow-md z-10">
83-
<div className="mx-auto px-6 h-16 flex items-center justify-between">
84-
<div className="flex items-center space-x-3">
85-
<div className="font-extrabold text-2xl tracking-tighter">
86-
Object<span className="text-gray-400">Stack</span>
82+
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
83+
<div className="container flex h-14 items-center px-4 md:px-6">
84+
<div className="mr-4 hidden md:flex items-center space-x-2">
85+
<div className="font-bold text-xl tracking-tight">
86+
Object<span className="text-muted-foreground">Stack</span>
8787
</div>
88-
<span className="px-2 py-0.5 rounded text-xs bg-gray-700 text-gray-300 border border-gray-600">
88+
<div className="hidden sm:inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80">
8989
Console
90-
</span>
90+
</div>
9191
</div>
92-
<div className="text-sm opacity-80 flex items-center gap-2">
93-
<div className="w-2 h-2 rounded-full bg-green-400"></div>
94-
v1.0.0 (Memory Kernel)
92+
<div className="flex flex-1 items-center justify-between space-x-2 md:justify-end">
93+
<div className="text-sm text-muted-foreground flex items-center gap-2">
94+
<span className="relative flex h-2 w-2">
95+
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"></span>
96+
<span className="relative inline-flex rounded-full h-2 w-2 bg-green-500"></span>
97+
</span>
98+
v1.0.0 (Memory Kernel)
99+
</div>
95100
</div>
96101
</div>
97102
</header>
98103

99104
{/* Main Layout */}
100105
<div className="flex flex-1 overflow-hidden">
101-
{/* Sidebar: Metadata Explorer */}
102-
<aside className="w-64 bg-white border-r border-gray-200 overflow-y-auto hidden md:block">
103-
<div className="p-4">
104-
<MetadataExplorer
105-
client={client}
106-
selectedObject={selectedObject}
107-
onSelectObject={(obj) => {
108-
setSelectedObject(obj);
109-
setView('list'); // Reset to list when changing objects
110-
}}
111-
/>
112-
</div>
113-
</aside>
114-
115-
{/* Main Content Area */}
116-
<main className="flex-1 overflow-y-auto p-6 relative">
117-
{selectedObject ? (
118-
<div className="space-y-6 max-w-7xl mx-auto">
119-
{/* Toolbar */}
120-
<div className="flex justify-between items-end pb-4 border-b border-gray-200">
121-
<div>
122-
<h1 className="text-2xl font-bold text-gray-900">
123-
{selectedObject}
124-
</h1>
125-
<p className="text-sm text-gray-500 mt-1">
126-
Manage records and view schema definition.
127-
</p>
128-
</div>
129-
<button
130-
onClick={handleCreate}
131-
className="px-4 py-2 bg-foreground text-white rounded hover:bg-black transition-colors shadow-sm font-medium flex items-center gap-2"
132-
>
133-
<span>+</span> New Record
134-
</button>
135-
</div>
106+
{/* Sidebar */}
107+
<aside className="hidden w-64 flex-col border-r bg-muted/10 md:flex">
108+
<div className="p-4 font-medium text-sm text-muted-foreground uppercase tracking-wider">
109+
Explorer
110+
</div>
111+
<div className="flex-1 overflow-hidden px-2 pb-4">
112+
<MetadataExplorer
113+
client={client}
114+
selectedObject={selectedObject}
115+
onSelectObject={(obj) => {
116+
setSelectedObject(obj);
117+
setView('list');
118+
setEditingRecord(null);
119+
}}
120+
/>
121+
</div>
122+
</aside>
136123

137-
{/* Data Table */}
138-
<ObjectDataTable
139-
key={selectedObject + view} // Force refresh when switching back
140-
client={client}
141-
objectApiName={selectedObject}
142-
onEdit={handleEdit}
143-
/>
144-
145-
</div>
146-
) : (
147-
<div className="flex flex-col items-center justify-center h-full text-gray-400">
148-
<div className="text-6xl mb-4">Select an Object</div>
149-
<p>Choose an object from the sidebar to manage data.</p>
150-
</div>
151-
)}
152-
</main>
124+
{/* Content Area */}
125+
<main className="flex-1 overflow-hidden p-4 md:p-6 flex flex-col bg-muted/5 relative">
126+
{selectedObject ? (
127+
<>
128+
<ObjectDataTable
129+
key={`${selectedObject}-${refreshKey}`}
130+
client={client}
131+
objectApiName={selectedObject}
132+
onEdit={handleEdit}
133+
/>
134+
{view === 'form' && (
135+
<ObjectDataForm
136+
client={client}
137+
objectApiName={selectedObject}
138+
record={editingRecord}
139+
onSuccess={handleFormSuccess}
140+
onCancel={() => setView('list')}
141+
/>
142+
)}
143+
</>
144+
) : (
145+
<div className="flex flex-col items-center justify-center h-full text-muted-foreground">
146+
<Database className="h-12 w-12 mb-4 opacity-20" />
147+
<div className="text-xl font-medium">Select an Object</div>
148+
<p className="opacity-60">Choose an object from the sidebar to manage data.</p>
149+
</div>
150+
)}
151+
</main>
153152
</div>
154-
155-
{/* Modal Form */}
156-
{view === 'form' && selectedObject && (
157-
<ObjectDataForm
158-
client={client}
159-
objectApiName={selectedObject}
160-
record={editingRecord}
161-
onSuccess={handleFormSuccess}
162-
onCancel={() => setView('list')}
163-
/>
164-
)}
165153
</div>
166154
);
167155
}

0 commit comments

Comments
 (0)