diff --git a/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/@create/_components/Create.tsx b/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/@create/_components/Create.tsx index 141ff38..8f48979 100644 --- a/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/@create/_components/Create.tsx +++ b/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/@create/_components/Create.tsx @@ -1,15 +1,13 @@ "use client"; -import { FC, useEffect } from "react"; +import { FC } from "react"; import { useFormState } from "react-dom"; -import { useRouter } from "next/navigation"; import { Grid } from "@mui/material"; import { TextField } from "ui"; import { Create as InternalCreate } from "@/app/_components/Create"; import { addFacebookBotAction } from "../../_actions/facebook"; export const Create: FC = () => { - const router = useRouter(); const initialState = { message: null, errors: {}, @@ -24,17 +22,12 @@ export const Create: FC = () => { initialState, ); - useEffect(() => { - if (formState.success) { - router.back(); - } - }, [formState.success, router]); - return ( diff --git a/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/@detail/_components/Detail.tsx b/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/@detail/_components/Detail.tsx index f7bfdc8..8d0b81e 100644 --- a/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/@detail/_components/Detail.tsx +++ b/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/@detail/_components/Detail.tsx @@ -2,9 +2,10 @@ import { FC } from "react"; import { Grid } from "@mui/material"; -import { DisplayTextField, Select } from "ui"; +import { DisplayTextField } from "ui"; import { FacebookBot } from "@/app/_lib/database"; import { Detail as InternalDetail } from "@/app/_components/Detail"; +import { deleteFacebookBotAction } from "../../_actions/facebook"; type DetailProps = { row: FacebookBot; @@ -12,9 +13,10 @@ type DetailProps = { export const Detail: FC = ({ row }) => ( diff --git a/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/@detail/page.tsx b/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/@detail/page.tsx index b9d90b3..b74b6ae 100644 --- a/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/@detail/page.tsx +++ b/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/@detail/page.tsx @@ -8,12 +8,17 @@ type Props = { }; export default async function Page({ params: { segment } }: Props) { - const id = segment[0]; + const id = segment?.[0]; + + if (!id) return null; + const row = await db .selectFrom("FacebookBot") .selectAll() .where("id", "=", id) .executeTakeFirst(); + if (!row) return null; + return ; } diff --git a/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/@edit/_components/Edit.tsx b/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/@edit/_components/Edit.tsx new file mode 100644 index 0000000..d4e1c89 --- /dev/null +++ b/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/@edit/_components/Edit.tsx @@ -0,0 +1,105 @@ +"use client"; + +import { FC } from "react"; +import { useFormState } from "react-dom"; +import { Grid } from "@mui/material"; +import { TextField } from "ui"; +import { FacebookBot } from "@/app/_lib/database"; +import { Edit as InternalEdit } from "@/app/_components/Edit"; +import { updateFacebookBotAction } from "../../_actions/facebook"; + +type EditProps = { + row: FacebookBot; +}; + +export const Edit: FC = ({ row }) => { + const initialState = { + message: null, + errors: {}, + values: row, + }; + const [formState, formAction] = useFormState( + updateFacebookBotAction, + initialState, + ); + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/@edit/page.tsx b/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/@edit/page.tsx new file mode 100644 index 0000000..55b424e --- /dev/null +++ b/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/@edit/page.tsx @@ -0,0 +1,24 @@ +import { db } from "@/app/_lib/database"; +import { Edit } from "./_components/Edit"; + +export const dynamic = "force-dynamic"; + +type Props = { + params: { segment: string[] }; +}; + +export default async function Page({ params: { segment } }: Props) { + const id = segment?.[0]; + + if (!id) return null; + + const row = await db + .selectFrom("FacebookBot") + .selectAll() + .where("id", "=", id) + .executeTakeFirst(); + + if (!row) return null; + + return ; +} diff --git a/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/_actions/facebook.ts b/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/_actions/facebook.ts index c913d75..21fcd35 100644 --- a/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/_actions/facebook.ts +++ b/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/_actions/facebook.ts @@ -1,28 +1,50 @@ "use server"; -import { revalidatePath } from "next/cache"; -import { db } from "@/app/_lib/database"; +import { addAction, updateAction, deleteAction } from "@/app/_lib/actions"; + +const entity = "facebook"; +const table = "FacebookBot"; export const addFacebookBotAction = async ( currentState: any, formData: FormData, ) => { - const newBot = { - name: formData.get("name")?.toString() ?? null, - description: formData.get("description")?.toString() ?? null, - appId: formData.get("appId")?.toString() ?? null, - appSecret: formData.get("appSecret")?.toString() ?? null, - pageId: formData.get("pageId")?.toString() ?? null, - pageAccessToken: formData.get("pageAccessToken")?.toString() ?? null, - }; - - await db.insertInto("FacebookBot").values(newBot).execute(); - - revalidatePath("/facebook"); - - return { - ...currentState, - values: newBot, - success: true, - }; + return addAction({ + entity, + table, + fields: [ + "name", + "description", + "appId", + "appSecret", + "pageId", + "pageAccessToken", + ], + currentState, + formData, + }); +}; + +export const updateFacebookBotAction = async ( + currentState: any, + formData: FormData, +) => { + return updateAction({ + entity, + table, + fields: [ + "name", + "description", + "appId", + "appSecret", + "pageId", + "pageAccessToken", + ], + currentState, + formData, + }); +}; + +export const deleteFacebookBotAction = async (id: string) => { + return deleteAction({ entity, table, id }); }; diff --git a/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/_components/FacebookBotsList.tsx b/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/_components/FacebookBotsList.tsx index a11c104..cde9613 100644 --- a/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/_components/FacebookBotsList.tsx +++ b/apps/bridge-frontend/app/(main)/facebook/[[...segment]]/_components/FacebookBotsList.tsx @@ -30,7 +30,7 @@ export const FacebookBotsList: FC = ({ rows }) => { return ( { + return addAction({ + entity: "signal", + table: "SignalBot", + fields: ["name", "description"], + currentState, + formData, + }); +}; + +export const updateSignalBotAction = async ( + currentState: any, + formData: FormData, +) => { + return updateAction({ + entity: "signal", + table: "SignalBot", + fields: ["name"], + currentState, + formData, + }); +}; + +export const updateSignalBotAction = async (id: string) => { + return deleteAction({ + entity: "facebook", + table: "FacebookBot", + id, + }); +}; diff --git a/apps/bridge-frontend/app/(main)/signal/_components/SignalBotsList.tsx b/apps/bridge-frontend/app/(main)/signal/_components/SignalBotsList.tsx index bf141a2..715d18a 100644 --- a/apps/bridge-frontend/app/(main)/signal/_components/SignalBotsList.tsx +++ b/apps/bridge-frontend/app/(main)/signal/_components/SignalBotsList.tsx @@ -37,6 +37,11 @@ export const SignalBotsList: FC = ({ rows }) => { ]; return ( - + ); }; diff --git a/apps/bridge-frontend/app/(main)/users/_actions/users.ts b/apps/bridge-frontend/app/(main)/users/_actions/users.ts new file mode 100644 index 0000000..17c7bd7 --- /dev/null +++ b/apps/bridge-frontend/app/(main)/users/_actions/users.ts @@ -0,0 +1,33 @@ +"use server"; + +import { addAction, updateAction, deleteAction } from "@/app/_lib/actions"; + +const entity = "users"; +const table = "User"; + +export const addUserAction = async (currentState: any, formData: FormData) => { + return addAction({ + entity, + table, + fields: ["name"], + currentState, + formData, + }); +}; + +export const updateUserAction = async ( + currentState: any, + formData: FormData, +) => { + return updateAction({ + entity, + table, + fields: ["name"], + currentState, + formData, + }); +}; + +export const deleteUserAction = async (id: string) => { + return deleteAction({ entity, table, id }); +}; diff --git a/apps/bridge-frontend/app/(main)/voice/_actions/voice.ts b/apps/bridge-frontend/app/(main)/voice/_actions/voice.ts new file mode 100644 index 0000000..ebac62c --- /dev/null +++ b/apps/bridge-frontend/app/(main)/voice/_actions/voice.ts @@ -0,0 +1,36 @@ +"use server"; + +import { addAction, updateAction, deleteAction } from "@/app/_lib/actions"; + +const entity = "voice"; +const table = "VoiceLine"; + +export const addVoiceLineAction = async ( + currentState: any, + formData: FormData, +) => { + return addAction({ + entity, + table, + fields: ["name"], + currentState, + formData, + }); +}; + +export const updateVoiceLineAction = async ( + currentState: any, + formData: FormData, +) => { + return updateAction({ + entity, + table, + fields: ["name"], + currentState, + formData, + }); +}; + +export const deleteVoiceLineAction = async (id: string) => { + return deleteAction({ entity, table, id }); +}; diff --git a/apps/bridge-frontend/app/(main)/voice/_components/VoiceBotsList.tsx b/apps/bridge-frontend/app/(main)/voice/_components/VoiceBotsList.tsx index 9eddf8c..3143e5a 100644 --- a/apps/bridge-frontend/app/(main)/voice/_components/VoiceBotsList.tsx +++ b/apps/bridge-frontend/app/(main)/voice/_components/VoiceBotsList.tsx @@ -36,5 +36,12 @@ export const VoiceBotsList: FC = ({ rows }) => { }, ]; - return ; + return ( + + ); }; diff --git a/apps/bridge-frontend/app/(main)/webhooks/_actions/webhooks.ts b/apps/bridge-frontend/app/(main)/webhooks/_actions/webhooks.ts new file mode 100644 index 0000000..5fb11ab --- /dev/null +++ b/apps/bridge-frontend/app/(main)/webhooks/_actions/webhooks.ts @@ -0,0 +1,36 @@ +"use server"; + +import { addAction, updateAction, deleteAction } from "@/app/_lib/actions"; + +const entity = "webhooks"; +const table = "Webhook"; + +export const addWebhookAction = async ( + currentState: any, + formData: FormData, +) => { + return addAction({ + entity, + table, + fields: ["name"], + currentState, + formData, + }); +}; + +export const updateWebhookAction = async ( + currentState: any, + formData: FormData, +) => { + return updateAction({ + entity, + table, + fields: ["name"], + currentState, + formData, + }); +}; + +export const deleteWebhookAction = async (id: string) => { + return deleteAction({ entity, table, id }); +}; diff --git a/apps/bridge-frontend/app/(main)/whatsapp/_actions/whatsapp.ts b/apps/bridge-frontend/app/(main)/whatsapp/_actions/whatsapp.ts new file mode 100644 index 0000000..7cbce39 --- /dev/null +++ b/apps/bridge-frontend/app/(main)/whatsapp/_actions/whatsapp.ts @@ -0,0 +1,36 @@ +"use server"; + +import { addAction, updateAction, deleteAction } from "@/app/_lib/actions"; + +const entity = "whatsapp"; +const table = "WhatsappBot"; + +export const addWhatsappBotAction = async ( + currentState: any, + formData: FormData, +) => { + return addAction({ + entity, + table, + fields: ["name"], + currentState, + formData, + }); +}; + +export const updateWhatsappBotAction = async ( + currentState: any, + formData: FormData, +) => { + return updateAction({ + entity, + table, + fields: ["name"], + currentState, + formData, + }); +}; + +export const deleteWhatsappBotAction = async (id: string) => { + return deleteAction({ entity, table, id }); +}; diff --git a/apps/bridge-frontend/app/(main)/whatsapp/_components/WhatsappList.tsx b/apps/bridge-frontend/app/(main)/whatsapp/_components/WhatsappList.tsx index 3fd2e71..c68e1d0 100644 --- a/apps/bridge-frontend/app/(main)/whatsapp/_components/WhatsappList.tsx +++ b/apps/bridge-frontend/app/(main)/whatsapp/_components/WhatsappList.tsx @@ -38,7 +38,7 @@ export const WhatsappList: FC = ({ rows }) => { return ( = ({ title, entity, formAction, + formState, children, }) => { const router = useRouter(); + useEffect(() => { + if (formState.success) { + router.back(); + } + }, [formState.success, router]); + return ( = ({ title, entity, id, children }) => { +export const Detail: FC = ({ + title, + entity, + id, + children, + deleteAction, +}) => { const router = useRouter(); + const { almostBlack } = colors; + const { bodyLarge } = typography; + const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false); + + const continueDeleteAction = async () => { + await deleteAction?.(id); + setShowDeleteConfirmation(false); + router.push(`/${entity}`); + }; return ( - router.push(`/${entity}`)} - buttons={ - - + <> + router.push(`/${entity}`)} + buttons={ + + + {deleteAction && ( + + + + + + } + > + + Are you sure you want to delete this record? + + + ); }; diff --git a/apps/bridge-frontend/app/_components/Edit.tsx b/apps/bridge-frontend/app/_components/Edit.tsx index f73b5ad..34c12d2 100644 --- a/apps/bridge-frontend/app/_components/Edit.tsx +++ b/apps/bridge-frontend/app/_components/Edit.tsx @@ -1,30 +1,55 @@ "use client"; -import { FC } from "react"; -import { Grid, Box } from "@mui/material"; +import { FC, useEffect } from "react"; +import { Grid } from "@mui/material"; import { useRouter } from "next/navigation"; -import { typography } from "@/app/_styles/theme"; +import { Button, Dialog } from "ui"; interface EditProps { title: string; entity: string; + formAction: any; + formState: any; children: any; } -export const Edit: FC = ({ title, entity, children }) => { +export const Edit: FC = ({ + title, + entity, + formState, + formAction, + children, +}) => { const router = useRouter(); - const { h3 } = typography; + + useEffect(() => { + if (formState.success) { + router.push(`/${entity}`); + } + }, [formState.success, router]); return ( - - - - {title} + router.push(`/${entity}`)} + buttons={ + + + ); }; diff --git a/apps/bridge-frontend/app/_components/InternalLayout.tsx b/apps/bridge-frontend/app/_components/InternalLayout.tsx index 6fa08ea..9674e8b 100644 --- a/apps/bridge-frontend/app/_components/InternalLayout.tsx +++ b/apps/bridge-frontend/app/_components/InternalLayout.tsx @@ -3,6 +3,7 @@ import { FC, PropsWithChildren, useState } from "react"; import { Grid } from "@mui/material"; import { CssBaseline } from "@mui/material"; +import { SessionProvider } from "next-auth/react"; import { css, Global } from "@emotion/react"; import { fonts } from "@/app/_styles/theme"; import { Sidebar } from "./Sidebar"; @@ -17,7 +18,7 @@ export const InternalLayout: FC = ({ children }) => { `; return ( - <> + @@ -29,6 +30,6 @@ export const InternalLayout: FC = ({ children }) => { {children as any} - + ); }; diff --git a/apps/bridge-frontend/app/_components/List.tsx b/apps/bridge-frontend/app/_components/List.tsx index 6b5f3bb..58c4063 100644 --- a/apps/bridge-frontend/app/_components/List.tsx +++ b/apps/bridge-frontend/app/_components/List.tsx @@ -4,7 +4,6 @@ import { FC } from "react"; import { GridColDef } from "@mui/x-data-grid-pro"; import { useRouter } from "next/navigation"; import { List as InternalList, Button } from "ui"; -import { colors } from "ui"; interface ListProps { title: string; @@ -15,7 +14,6 @@ interface ListProps { export const List: FC = ({ title, entity, rows, columns }) => { const router = useRouter(); - const { mediumBlue } = colors; const onRowClick = (id: string) => { router.push(`/${entity}/${id}`); @@ -28,7 +26,7 @@ export const List: FC = ({ title, entity, rows, columns }) => { columns={columns} onRowClick={onRowClick} buttons={ -