diff --git a/src/components/tables/index.ts b/src/components/tables/index.ts
index 550d730..0df9ff5 100644
--- a/src/components/tables/index.ts
+++ b/src/components/tables/index.ts
@@ -4,6 +4,7 @@ import comment from "../../comment";
import type { File, HookFile } from "../../types";
import { parseNameFormats } from "../../utils";
import { mapHookFileToCreateComponent } from "./create";
+import { mapHookFileToUpdateComponent } from "./update";
import { mapHookFileToDeleteComponent } from "./delete";
import { mapHookFileToGetComponent } from "./get";
@@ -17,6 +18,7 @@ export const mapHookFileToComponent = async (
const componentName = fileName.replace("use", "");
const getComponentName = `Get${componentName}`;
const createComponentName = `Create${componentName}`;
+ const updateComponentName = `Update${componentName}`;
const deleteComponentName = `Delete${componentName}`;
const { camelCasePlural, pascalCase, pascalCasePlural } =
parseNameFormats(componentName);
@@ -29,15 +31,17 @@ export const mapHookFileToComponent = async (
import ${fileName} from "../../hooks/${fileName}";
import ${getComponentName} from "./${getComponentName}";
import ${createComponentName} from "./${createComponentName}";
+ import ${updateComponentName} from "./${updateComponentName}";
import ${deleteComponentName} from "./${deleteComponentName}";
export default function ${componentName}() {
- const { ${camelCasePlural}, fetch${pascalCasePlural}, create${pascalCase}, delete${pascalCase} } = ${fileName}();
+ const { ${camelCasePlural}, fetch${pascalCasePlural}, create${pascalCase}, update${pascalCase}, delete${pascalCase} } = ${fileName}();
return (
<${getComponentName} ${camelCasePlural}={${camelCasePlural}} onFetch={fetch${pascalCasePlural}} />
<${createComponentName} onCreate={create${pascalCase}} onFetch={fetch${pascalCasePlural}} />
+ <${updateComponentName} onUpdate={update${pascalCase}} onFetch={fetch${pascalCasePlural}} />
<${deleteComponentName} onDelete={delete${pascalCase}} onFetch={fetch${pascalCasePlural}} />
)
@@ -67,6 +71,9 @@ export const parseComponentFilesForTables = async (
const createComponentPromises = tableHookFiles.map((tableHookFile) =>
mapHookFileToCreateComponent(tableHookFile, tables)
);
+ const updateComponentPromises = tableHookFiles.map((tableHookFile) =>
+ mapHookFileToUpdateComponent(tableHookFile, tables)
+ );
const deleteComponentPromises = tableHookFiles.map((tableHookFile) =>
mapHookFileToDeleteComponent(tableHookFile, tables)
);
@@ -74,6 +81,7 @@ export const parseComponentFilesForTables = async (
const files = await Promise.all([
...componentPromises,
...createComponentPromises,
+ ...updateComponentPromises,
...getComponentPromises,
...deleteComponentPromises,
]);
diff --git a/src/components/tables/update.ts b/src/components/tables/update.ts
new file mode 100644
index 0000000..9b0e50f
--- /dev/null
+++ b/src/components/tables/update.ts
@@ -0,0 +1,208 @@
+import prettier from "prettier";
+import comment from "../../comment";
+import type { ColumnResponse, TablesResponse } from "../../pgMeta/fetchTables";
+import type { File, HookFile } from "../../types";
+import { parseNameFormats } from "../../utils";
+
+const mapColumns = (
+ columns?: ColumnResponse[]
+): { fields: string; inputs: string } => {
+ if (!columns) {
+ return { fields: "", inputs: "" };
+ }
+
+ const filteredColumns = columns.filter(
+ (column) => column.isIdentity || column.isUpdatable
+ );
+ const fields = filteredColumns
+ .filter((column) => !column.isIdentity)
+ .map((column) => `"${column.name}"`)
+ .join(",");
+ const inputs = filteredColumns
+ .map((column, index) => {
+ const label = column.isIdentity ? `${column.name}*` : column.name;
+ return `
+
+
+
+ 0 ? 'marginTop: "10px",' : ""}
+ background: "#000",
+ color: "#fff",
+ border: "1px solid #34383A",
+ marginLeft: "10px",
+ flex: "1",
+ borderRadius: "0.375rem",
+ padding: "4px 16px",
+ }}
+ />
+
+ `;
+ })
+ .join(" ");
+
+ return { fields, inputs };
+};
+
+export const mapHookFileToUpdateComponent = async (
+ hookFile: HookFile,
+ tables: TablesResponse
+): Promise => {
+ const {
+ entityName,
+ file: { fileName },
+ } = hookFile;
+
+ const table = tables.find((table) => table.name === entityName);
+ const componentName = `${fileName.replace("use", "")}`;
+ const { pascalCase } = parseNameFormats(componentName);
+
+ const { fields, inputs } = mapColumns(table?.columns);
+
+ const content = `
+ ${comment}
+
+ "use client";
+
+ import { FormEventHandler, MouseEventHandler, useState } from "react";
+ import type { Row, Update${pascalCase} } from "../../hooks/${fileName}";
+
+ const fields: Array = [${fields}]
+
+ export default function Update${componentName}({
+ onUpdate,
+ onFetch
+ }: {
+ onUpdate: (id: Row["id"], updatedRow: Update${pascalCase}) => Promise,
+ onFetch: () => Promise
+ }) {
+ const [message, setMessage] = useState();
+
+ const handleSubmit: FormEventHandler = (event) => {
+ event.preventDefault();
+ const target = event.target as typeof event.target & Update${pascalCase};
+ const id = (target["id"] as any)?.value;
+ const updatedRow = fields
+ .map((field) => ({ field, value: (target[field] as any)?.value }))
+ .reduce((newRow, { field,value }) => {
+ if (value.trim() !== "") {
+ newRow[field] = value;
+ }
+ return newRow;
+ }, {} as Record);
+ onUpdate(id, updatedRow)
+ .then((task) => {
+ if (task) {
+ setMessage("row with id " + task.id + " updated!");
+ onFetch();
+ } else {
+ setMessage("failed to update row!");
+ }
+ })
+ .catch((error) => {
+ if (error.message) {
+ setMessage(error.message);
+ } else {
+ setMessage("failed to update row!");
+ }
+ });
+ };
+
+ const handleClick: MouseEventHandler = () => {
+ setMessage(undefined);
+ }
+
+ if (message) {
+ return
+ {message}
+
+
+ }
+
+ return (
+
+ );
+ }
+ `;
+
+ const formattedContent = await prettier.format(content, {
+ parser: "typescript",
+ });
+
+ return {
+ fileName: `Update${componentName}.tsx`,
+ content: formattedContent,
+ };
+};
diff --git a/src/hooks/table.ts b/src/hooks/table.ts
index 79fdf68..0daae99 100644
--- a/src/hooks/table.ts
+++ b/src/hooks/table.ts
@@ -29,17 +29,17 @@ const mapTableToFile = async (table: TableResponse): Promise => {
}, []);
const fetch${pascalCasePlural} = async() => {
- try {
- const { data, error } = await supabase
- .from("${tableName}")
- .select();
- if (error) {
- throw error;
- }
- set${pascalCasePlural}(data || []);
- } catch (error) {
- console.error("Error fetching", error);
+ try {
+ const { data, error } = await supabase
+ .from("${tableName}")
+ .select();
+ if (error) {
+ throw error;
}
+ set${pascalCasePlural}(data || []);
+ } catch (error) {
+ console.error("Error fetching", error);
+ }
};
const create${pascalCase} = async (newData: Insert${pascalCase}) => {
@@ -55,23 +55,20 @@ const mapTableToFile = async (table: TableResponse): Promise => {
};
const update${pascalCase} = async (id: Row["id"], updatedData: Update${pascalCase}) => {
- try {
- const { data, error } = await supabase
- .from("${tableName}")
- .update(updatedData)
- .eq("id", id)
- .select();
- if (error) {
- throw error;
- }
- set${pascalCasePlural}(
- ${camelCasePlural}.map((${camelCase}) =>
- ${camelCase}.id === id ? { ...${camelCase}, ...data[0] } : ${camelCase}
- )
- );
- } catch (error) {
- console.error("Error updating alert:", error);
+ const { data, error } = await supabase
+ .from("${tableName}")
+ .update(updatedData)
+ .eq("id", id)
+ .select();
+ if (error) {
+ throw error;
}
+ set${pascalCasePlural}(
+ ${camelCasePlural}.map((${camelCase}) =>
+ ${camelCase}.id === id ? { ...${camelCase}, ...data[0] } : ${camelCase}
+ )
+ );
+ return data[0];
};
const delete${pascalCase} = async (id: Row["id"]): Promise => {