mirror of
https://github.com/johndoe6345789/postgres.git
synced 2026-04-24 13:55:00 +00:00
Refactor admin dashboard to be config-driven with features.json
Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
2
package-lock.json
generated
2
package-lock.json
generated
@@ -81,7 +81,7 @@
|
||||
"storybook": "^10.1.11",
|
||||
"tailwindcss": "^4.1.17",
|
||||
"tsx": "^4.21.0",
|
||||
"typescript": "^5.9.3",
|
||||
"typescript": "5.9.3",
|
||||
"vite-tsconfig-paths": "^5.1.4",
|
||||
"vitest": "^4.0.15",
|
||||
"vitest-browser-react": "^2.0.2"
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
"storybook": "^10.1.11",
|
||||
"tailwindcss": "^4.1.17",
|
||||
"tsx": "^4.21.0",
|
||||
"typescript": "^5.9.3",
|
||||
"typescript": "5.9.3",
|
||||
"vite-tsconfig-paths": "^5.1.4",
|
||||
"vitest": "^4.0.15",
|
||||
"vitest-browser-react": "^2.0.2"
|
||||
|
||||
1161
src/app/admin/dashboard/page-old.tsx
Normal file
1161
src/app/admin/dashboard/page-old.tsx
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
72
src/components/admin/SQLQueryTab.tsx
Normal file
72
src/components/admin/SQLQueryTab.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
'use client';
|
||||
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
CircularProgress,
|
||||
Paper,
|
||||
TextField,
|
||||
Typography,
|
||||
} from '@mui/material';
|
||||
import { useState } from 'react';
|
||||
import { getFeatureById } from '@/utils/featureConfig';
|
||||
|
||||
type SQLQueryTabProps = {
|
||||
onExecuteQuery: (query: string) => Promise<void>;
|
||||
};
|
||||
|
||||
export default function SQLQueryTab({ onExecuteQuery }: SQLQueryTabProps) {
|
||||
const [queryText, setQueryText] = useState('');
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
// Get feature configuration from JSON
|
||||
const feature = getFeatureById('sql-query');
|
||||
|
||||
const handleExecute = async () => {
|
||||
if (!queryText.trim()) {
|
||||
return;
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
try {
|
||||
await onExecuteQuery(queryText);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Typography variant="h5" gutterBottom>
|
||||
{feature?.name || 'SQL Query Interface'}
|
||||
</Typography>
|
||||
|
||||
{feature?.description && (
|
||||
<Typography variant="body2" color="text.secondary" gutterBottom>
|
||||
{feature.description}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
<Paper sx={{ p: 2, mt: 2 }}>
|
||||
<TextField
|
||||
fullWidth
|
||||
multiline
|
||||
rows={6}
|
||||
label="SQL Query (SELECT only)"
|
||||
variant="outlined"
|
||||
value={queryText}
|
||||
onChange={e => setQueryText(e.target.value)}
|
||||
placeholder="SELECT * FROM your_table LIMIT 10;"
|
||||
sx={{ mb: 2 }}
|
||||
/>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={handleExecute}
|
||||
disabled={loading || !queryText.trim()}
|
||||
>
|
||||
{loading ? <CircularProgress size={24} /> : 'Execute Query'}
|
||||
</Button>
|
||||
</Paper>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
72
src/components/admin/TablesTab.tsx
Normal file
72
src/components/admin/TablesTab.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
'use client';
|
||||
|
||||
import StorageIcon from '@mui/icons-material/Storage';
|
||||
import {
|
||||
Box,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemButton,
|
||||
ListItemIcon,
|
||||
ListItemText,
|
||||
Paper,
|
||||
Typography,
|
||||
} from '@mui/material';
|
||||
import { getFeatureById } from '@/utils/featureConfig';
|
||||
|
||||
type TablesTabProps = {
|
||||
tables: Array<{ table_name: string }>;
|
||||
selectedTable: string;
|
||||
onTableClick: (tableName: string) => void;
|
||||
};
|
||||
|
||||
export default function TablesTab({
|
||||
tables,
|
||||
selectedTable,
|
||||
onTableClick,
|
||||
}: TablesTabProps) {
|
||||
// Get feature configuration from JSON
|
||||
const feature = getFeatureById('database-crud');
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Typography variant="h5" gutterBottom>
|
||||
{feature?.name || 'Database Tables'}
|
||||
</Typography>
|
||||
|
||||
{feature?.description && (
|
||||
<Typography variant="body2" color="text.secondary" gutterBottom>
|
||||
{feature.description}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
<Paper sx={{ mt: 2, mb: 2 }}>
|
||||
<List>
|
||||
{tables.map(table => (
|
||||
<ListItem key={table.table_name} disablePadding>
|
||||
<ListItemButton
|
||||
selected={selectedTable === table.table_name}
|
||||
onClick={() => onTableClick(table.table_name)}
|
||||
>
|
||||
<ListItemIcon>
|
||||
<StorageIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={table.table_name} />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
))}
|
||||
{tables.length === 0 && (
|
||||
<ListItem>
|
||||
<ListItemText primary="No tables found" />
|
||||
</ListItem>
|
||||
)}
|
||||
</List>
|
||||
</Paper>
|
||||
|
||||
{selectedTable && (
|
||||
<Typography variant="h6" gutterBottom>
|
||||
Table: {selectedTable}
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -2863,6 +2863,12 @@
|
||||
"icon": "TableChart",
|
||||
"featureId": "table-management"
|
||||
},
|
||||
{
|
||||
"id": "column-manager",
|
||||
"label": "Column Manager",
|
||||
"icon": "ViewColumn",
|
||||
"featureId": "column-management"
|
||||
},
|
||||
{
|
||||
"id": "constraints",
|
||||
"label": "Constraints",
|
||||
|
||||
Reference in New Issue
Block a user