mirror of
https://github.com/johndoe6345789/postgres.git
synced 2026-04-24 13:55:00 +00:00
Refactor admin components to use atomic component library and add utilities
Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
@@ -1,23 +1,21 @@
|
||||
'use client';
|
||||
|
||||
import AddIcon from '@mui/icons-material/Add';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import { useState } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Checkbox,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
FormControlLabel,
|
||||
IconButton,
|
||||
Checkbox,
|
||||
MenuItem,
|
||||
Select,
|
||||
TextField,
|
||||
Typography,
|
||||
} from '@mui/material';
|
||||
import { useState } from 'react';
|
||||
} from '../atoms';
|
||||
import Button from '../atoms/Button';
|
||||
import TextField from '../atoms/TextField';
|
||||
import Typography from '../atoms/Typography';
|
||||
import IconButton from '../atoms/IconButton';
|
||||
|
||||
type Column = {
|
||||
name: string;
|
||||
@@ -141,21 +139,15 @@ export default function CreateTableDialog({
|
||||
sx={{ mr: 1 }}
|
||||
/>
|
||||
{columns.length > 1 && (
|
||||
<IconButton onClick={() => removeColumn(index)} color="error" size="small">
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
<IconButton onClick={() => removeColumn(index)} color="error" size="small" icon="Delete" />
|
||||
)}
|
||||
</Box>
|
||||
))}
|
||||
<Button startIcon={<AddIcon />} onClick={addColumn} variant="outlined">
|
||||
Add Column
|
||||
</Button>
|
||||
<Button startIcon="Add" onClick={addColumn} variant="outlined" text="Add Column" />
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={handleClose}>Cancel</Button>
|
||||
<Button onClick={handleCreate} variant="contained" disabled={loading || !tableName.trim()}>
|
||||
Create Table
|
||||
</Button>
|
||||
<Button onClick={handleClose} text="Cancel" />
|
||||
<Button onClick={handleCreate} variant="contained" disabled={loading || !tableName.trim()} text="Create Table" />
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
TableHead,
|
||||
TableRow,
|
||||
Tooltip,
|
||||
} from '@mui/material';
|
||||
} from '../atoms';
|
||||
import IconButton from '../atoms/IconButton';
|
||||
|
||||
type DataGridProps = {
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
MenuItem,
|
||||
Select,
|
||||
Typography,
|
||||
} from '@mui/material';
|
||||
import { useState } from 'react';
|
||||
} from '../atoms';
|
||||
import Button from '../atoms/Button';
|
||||
import Typography from '../atoms/Typography';
|
||||
|
||||
type DropTableDialogProps = {
|
||||
open: boolean;
|
||||
@@ -70,15 +70,14 @@ export default function DropTableDialog({
|
||||
</Select>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={handleClose}>Cancel</Button>
|
||||
<Button onClick={handleClose} text="Cancel" />
|
||||
<Button
|
||||
onClick={handleDrop}
|
||||
color="error"
|
||||
variant="contained"
|
||||
disabled={loading || !selectedTable}
|
||||
>
|
||||
Drop Table
|
||||
</Button>
|
||||
text="Drop Table"
|
||||
/>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
52
src/components/atoms/Button.generated.stories.tsx
Normal file
52
src/components/atoms/Button.generated.stories.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import Button from './Button';
|
||||
import { generateMeta, generateStories } from '@/utils/storybook/storyGenerator';
|
||||
|
||||
/**
|
||||
* Example of using story generator with features.json configuration
|
||||
* This demonstrates how to leverage the storybookStories section from features.json
|
||||
*/
|
||||
|
||||
// Generate meta from features.json
|
||||
const meta = generateMeta(Button, 'Button', {
|
||||
title: 'Atoms/Button',
|
||||
}) satisfies Meta<typeof Button>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
// Generate stories from features.json
|
||||
const generatedStories = generateStories<typeof Button>('Button');
|
||||
|
||||
// Export individual stories
|
||||
export const Primary: Story = generatedStories.primary || {
|
||||
args: {
|
||||
variant: 'contained',
|
||||
color: 'primary',
|
||||
text: 'Primary Button',
|
||||
},
|
||||
};
|
||||
|
||||
export const Secondary: Story = generatedStories.secondary || {
|
||||
args: {
|
||||
variant: 'outlined',
|
||||
color: 'secondary',
|
||||
text: 'Secondary Button',
|
||||
},
|
||||
};
|
||||
|
||||
export const WithIcon: Story = generatedStories.withIcon || {
|
||||
args: {
|
||||
variant: 'contained',
|
||||
startIcon: 'Add',
|
||||
text: 'Add Item',
|
||||
},
|
||||
};
|
||||
|
||||
export const Loading: Story = generatedStories.loading || {
|
||||
args: {
|
||||
variant: 'contained',
|
||||
disabled: true,
|
||||
text: 'Loading...',
|
||||
},
|
||||
};
|
||||
@@ -44,4 +44,5 @@ export {
|
||||
AccordionSummary,
|
||||
AccordionDetails,
|
||||
Chip,
|
||||
Tooltip,
|
||||
} from '@mui/material';
|
||||
|
||||
76
src/utils/storybook/storyGenerator.ts
Normal file
76
src/utils/storybook/storyGenerator.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { getAllStorybookStories, getStorybookStoriesForComponent, StorybookStory } from '@/utils/featureConfig';
|
||||
|
||||
/**
|
||||
* Generate Storybook meta configuration from features.json
|
||||
*/
|
||||
export function generateMeta<T>(
|
||||
component: T,
|
||||
componentName: string,
|
||||
customMeta?: Partial<Meta<T>>
|
||||
): Meta<T> {
|
||||
const stories = getStorybookStoriesForComponent(componentName);
|
||||
const defaultStory = stories.default;
|
||||
|
||||
return {
|
||||
title: `Components/${componentName}`,
|
||||
component: component as any,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
...defaultStory?.parameters,
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
...customMeta,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a single story from features.json story definition
|
||||
*/
|
||||
export function generateStory<T>(
|
||||
storyConfig: StorybookStory
|
||||
): StoryObj<T> {
|
||||
return {
|
||||
name: storyConfig.name,
|
||||
args: storyConfig.args || {},
|
||||
parameters: storyConfig.parameters,
|
||||
// Note: play functions would need to be converted from strings to actual functions
|
||||
// This is a limitation of JSON - we can only store the play steps as strings
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate all stories for a component from features.json
|
||||
*/
|
||||
export function generateStories<T>(componentName: string): Record<string, StoryObj<T>> {
|
||||
const stories = getStorybookStoriesForComponent(componentName);
|
||||
const result: Record<string, StoryObj<T>> = {};
|
||||
|
||||
for (const [key, storyConfig] of Object.entries(stories)) {
|
||||
result[key] = generateStory<T>(storyConfig);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available story configurations
|
||||
*/
|
||||
export function listStorybookComponents(): string[] {
|
||||
return Object.keys(getAllStorybookStories());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to create mock handlers for stories
|
||||
*/
|
||||
export function createMockHandlers(handlerNames: string[]): Record<string, () => void> {
|
||||
const handlers: Record<string, () => void> = {};
|
||||
|
||||
for (const name of handlerNames) {
|
||||
handlers[name] = () => {
|
||||
console.log(`Mock handler called: ${name}`);
|
||||
};
|
||||
}
|
||||
|
||||
return handlers;
|
||||
}
|
||||
Reference in New Issue
Block a user