Skip to content

Commit

Permalink
feat: converted wizard dummy file to ts, added additional testcases (#…
Browse files Browse the repository at this point in the history
…911)

converted the generateCode dummy file to TS and added additional
testcases.
  • Loading branch information
Kevin101Zhang authored Jul 23, 2024
1 parent a39f835 commit b29d8b6
Show file tree
Hide file tree
Showing 6 changed files with 334 additions and 188 deletions.
124 changes: 62 additions & 62 deletions frontend/src/components/Editor/EditorComponents/GenerateCode.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,71 +2,71 @@
import { useState } from 'react';

const GenerateCode = () => {
const [contractFilter, setContractFilter] = useState('');
const [selectedMethods, setSelectedMethods] = useState([]);
const [selectedEvents, setSelectedEvents] = useState([]);
const [generatedCode, setGeneratedCode] = useState({ jsCode: '', sqlCode: '' });
const [contractFilter, setContractFilter] = useState('');
const [selectedMethods, setSelectedMethods] = useState([]);
const [selectedEvents, setSelectedEvents] = useState([]);
const [generatedCode, setGeneratedCode] = useState({ jsCode: '', sqlCode: '' });

const handleGenerateCode = async () => {
const response = await fetch('/api/generateCode', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ contractFilter, selectedMethods, selectedEvents }),
});
const data = await response.json();
setGeneratedCode(data);
};
const handleGenerateCode = async () => {
const response = await fetch('/api/generateCode', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ contractFilter, selectedMethods, selectedEvents }),
});
const data = await response.json();
setGeneratedCode(data);
};

return (
<div className="min-h-screen bg-gray-100 p-6">
<div className="max-w-3xl mx-auto bg-white p-8 shadow-lg rounded-lg">
<h1 className="text-3xl font-bold mb-6">Generate Code</h1>
<div className="mb-4">
<input
type="text"
placeholder="Contract Filter"
value={contractFilter}
onChange={(e) => setContractFilter(e.target.value)}
className="w-full p-3 border border-gray-300 rounded-md"
/>
</div>
<div className="mb-4">
<input
type="text"
placeholder="Selected Methods (comma separated)"
value={selectedMethods}
onChange={(e) => setSelectedMethods(e.target.value.split(','))}
className="w-full p-3 border border-gray-300 rounded-md"
/>
</div>
<div className="mb-4">
<input
type="text"
placeholder="Selected Events (comma separated)"
value={selectedEvents}
onChange={(e) => setSelectedEvents(e.target.value.split(','))}
className="w-full p-3 border border-gray-300 rounded-md"
/>
</div>
<button
onClick={handleGenerateCode}
className="w-full bg-blue-500 text-white py-3 rounded-md hover:bg-blue-600 transition duration-200"
>
Generate Code
</button>
<div className="mt-6">
<h2 className="text-2xl font-semibold mb-4">Generated JavaScript Code</h2>
<pre className="bg-gray-200 p-4 rounded-md whitespace-pre-wrap">{generatedCode.jsCode}</pre>
</div>
<div className="mt-6">
<h2 className="text-2xl font-semibold mb-4">Generated SQL Code</h2>
<pre className="bg-gray-200 p-4 rounded-md whitespace-pre-wrap">{generatedCode.sqlCode}</pre>
</div>
</div>
return (
<div className="min-h-screen bg-gray-100 p-6">
<div className="max-w-3xl mx-auto bg-white p-8 shadow-lg rounded-lg">
<h1 className="text-3xl font-bold mb-6">Generate Code</h1>
<div className="mb-4">
<input
type="text"
placeholder="Contract Filter"
value={contractFilter}
onChange={(e) => setContractFilter(e.target.value)}
className="w-full p-3 border border-gray-300 rounded-md"
/>
</div>
);
<div className="mb-4">
<input
type="text"
placeholder="Selected Methods (comma separated)"
value={selectedMethods}
onChange={(e) => setSelectedMethods(e.target.value.split(','))}
className="w-full p-3 border border-gray-300 rounded-md"
/>
</div>
<div className="mb-4">
<input
type="text"
placeholder="Selected Events (comma separated)"
value={selectedEvents}
onChange={(e) => setSelectedEvents(e.target.value.split(','))}
className="w-full p-3 border border-gray-300 rounded-md"
/>
</div>
<button
onClick={handleGenerateCode}
className="w-full bg-blue-500 text-white py-3 rounded-md hover:bg-blue-600 transition duration-200"
>
Generate Code
</button>
<div className="mt-6">
<h2 className="text-2xl font-semibold mb-4">Generated JavaScript Code</h2>
<pre className="bg-gray-200 p-4 rounded-md whitespace-pre-wrap">{generatedCode.jsCode}</pre>
</div>
<div className="mt-6">
<h2 className="text-2xl font-semibold mb-4">Generated SQL Code</h2>
<pre className="bg-gray-200 p-4 rounded-md whitespace-pre-wrap">{generatedCode.sqlCode}</pre>
</div>
</div>
</div>
);
};

export default GenerateCode;
71 changes: 0 additions & 71 deletions frontend/src/pages/api/generateCode.js

This file was deleted.

98 changes: 98 additions & 0 deletions frontend/src/pages/api/generateCode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import type { NextApiRequest, NextApiResponse } from 'next';

import { defaultCode, defaultSchema } from '../../utils/formatters';

interface RequestBody {
contractFilter: string | string[];
selectedMethods: string[];
selectedEvents: string[];
}

const validateRequestBody = (body: any): body is RequestBody => {
const isStringOrArray = (value: any): value is string | string[] =>
typeof value === 'string' || (Array.isArray(value) && value.every((item) => typeof item === 'string'));

return (
isStringOrArray(body.contractFilter) &&
Array.isArray(body.selectedMethods) &&
body.selectedMethods.every((method: any) => typeof method === 'string') &&
Array.isArray(body.selectedEvents) &&
body.selectedEvents.every((event: any) => typeof event === 'string')
);
};

const generateDummyJSCode = (
contractFilter: string | string[],
selectedMethods: string[],
selectedEvents: string[],
): string => {
const filterString = Array.isArray(contractFilter) ? contractFilter.join(', ') : contractFilter;
const jsCodeHeader =
`// JavaScript Code\n\n` +
`-- Contract Filter: ${filterString}\n\n` +
`-- Selected Methods: ${selectedMethods.join(', ')}\n\n` +
`-- Selected Events: ${selectedEvents.join(', ')}\n\n`;

const methodsJS = selectedMethods
.map((method) => `function ${method}() {\n console.log('Executing ${method}');\n}\n\n`)
.join('');

const eventsJS = selectedEvents
.map((event) => `function handle${event}() {\n console.log('Handling event ${event}');\n}\n\n`)
.join('');

return jsCodeHeader + defaultCode + methodsJS + eventsJS;
};

const generateDummySQLCode = (
contractFilter: string | string[],
selectedMethods: string[],
selectedEvents: string[],
): string => {
const filterString = Array.isArray(contractFilter) ? contractFilter.join(', ') : contractFilter;
const sqlCodeHeader =
`-- SQL Code\n\n` +
`-- Contract Filter: ${filterString}\n\n` +
`-- Selected Methods: ${selectedMethods.join(', ')}\n\n` +
`-- Selected Events: ${selectedEvents.join(', ')}\n\n`;

const methodsSQL = selectedMethods
.map((method) => `-- Method: ${method}\nINSERT INTO methods (name) VALUES ('${method}');\n\n`)
.join('');

const eventsSQL = selectedEvents
.map((event) => `-- Event: ${event}\nINSERT INTO events (name) VALUES ('${event}');\n\n`)
.join('');

return sqlCodeHeader + defaultSchema + methodsSQL + eventsSQL;
};

export default function handler(req: NextApiRequest, res: NextApiResponse): void {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'POST');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');

if (req.method === 'OPTIONS') {
res.status(200).end();
return;
}
if (req.method !== 'POST') {
res.status(405).json({ error: 'Method Not Allowed' });
return;
}

if (!validateRequestBody(req.body)) {
res.status(400).json({
error:
'Invalid request body: contractFilter must be a string or an array of strings, and selectedMethods and selectedEvents must be arrays of strings',
});
return;
}

const { contractFilter, selectedMethods, selectedEvents } = req.body;

const jsCode = generateDummyJSCode(contractFilter, selectedMethods, selectedEvents);
const sqlCode = generateDummySQLCode(contractFilter, selectedMethods, selectedEvents);

res.status(200).json({ jsCode, sqlCode });
}
6 changes: 2 additions & 4 deletions frontend/src/pages/query-api-editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import React, { useContext, useEffect } from 'react';
import { Alert } from 'react-bootstrap';

import Editor from '@/components/Editor/EditorComponents/Editor';
import GenerateCode from '@/components/Editor/EditorComponents/GenerateCode';
import IndexerLogsContainer from '@/components/Logs/LogsViewContainer/IndexerLogsContainer';
import { IndexerDetailsContext } from '@/contexts/IndexerDetailsContext';
import GenerateCode from '@/components/Editor/EditorComponents/GenerateCode';

const QueryApiEditorPage = ({ router }) => {
const { accountId, indexerName } = router.query;
Expand All @@ -26,9 +26,7 @@ const QueryApiEditorPage = ({ router }) => {
}

if (accountId == 'test' || indexerName == 'test') {
return (
<GenerateCode />
);
return <GenerateCode />;
}

return showLogsView ? <IndexerLogsContainer /> : <Editor />;
Expand Down
Loading

0 comments on commit b29d8b6

Please sign in to comment.