From e444ac68900c09607512fa884a35b82b834216a1 Mon Sep 17 00:00:00 2001 From: Bhavya Gor Date: Sat, 29 Jun 2024 18:10:02 +0530 Subject: [PATCH] multiple changes --- .../nextjs/app/dashboard/[productID]/page.tsx | 4 +- packages/nextjs/components/ButtonsList.tsx | 23 ++-- packages/nextjs/components/Footer.tsx | 17 +-- packages/nextjs/components/FrameEditor.tsx | 2 +- packages/nextjs/components/FrameRenderer.tsx | 6 +- packages/nextjs/components/FramesSidebar.tsx | 43 ++++++-- packages/nextjs/providers/ProductProvider.tsx | 101 +++++++++++++++--- 7 files changed, 137 insertions(+), 59 deletions(-) diff --git a/packages/nextjs/app/dashboard/[productID]/page.tsx b/packages/nextjs/app/dashboard/[productID]/page.tsx index 6fa3b9d..9479d6a 100644 --- a/packages/nextjs/app/dashboard/[productID]/page.tsx +++ b/packages/nextjs/app/dashboard/[productID]/page.tsx @@ -9,11 +9,11 @@ import { ProvideProduct } from "~~/providers/ProductProvider"; const Product: NextPage = () => { return ( -
+
-
+
diff --git a/packages/nextjs/components/ButtonsList.tsx b/packages/nextjs/components/ButtonsList.tsx index db26767..65f0ee3 100644 --- a/packages/nextjs/components/ButtonsList.tsx +++ b/packages/nextjs/components/ButtonsList.tsx @@ -4,18 +4,11 @@ import { FrameButtonMetadata, FrameMetadataType } from "@coinbase/onchainkit"; import { IconButton } from "@mui/material"; import { PlusIcon } from "@heroicons/react/24/outline"; import { useProductJourney } from "~~/providers/ProductProvider"; -import { saveFrame } from "~~/services/frames"; import { notification } from "~~/utils/scaffold-eth"; const ButtonList = () => { - const { currentFrame, setCurrentFrame, frame } = useProductJourney(); - + const { currentFrame, setCurrentFrame, frame, saveFrame } = useProductJourney(); const [activeButtonIndex, setActiveButtonIndex] = useState(0); - useEffect(() => { - console.log("currentFrame", currentFrame); - console.log(activeButtonIndex); - console.log(currentFrame?.buttons[activeButtonIndex]); - }, [currentFrame, activeButtonIndex]); if (!currentFrame) return null; const handleAddButton = () => { @@ -39,12 +32,11 @@ const ButtonList = () => { const handleSaveFrame = async () => { notification.info("Frame saved successfully"); - const updatedFrame = await saveFrame({ + await saveFrame.mutateAsync({ _id: frame?._id as string, name: frame?.name as string, frameJson: currentFrame as FrameMetadataType, }); - console.log(updatedFrame); }; const handleSave = (button: FrameButtonMetadata) => { @@ -100,9 +92,14 @@ const ButtonList = () => { {currentFrame?.buttons[activeButtonIndex] && ( )} - +
+ + +
); }; diff --git a/packages/nextjs/components/Footer.tsx b/packages/nextjs/components/Footer.tsx index 571fc36..3c2b612 100644 --- a/packages/nextjs/components/Footer.tsx +++ b/packages/nextjs/components/Footer.tsx @@ -1,20 +1,5 @@ import React from "react"; -import { hardhat } from "viem/chains"; -import { SwitchTheme } from "~~/components/SwitchTheme"; -import { useTargetNetwork } from "~~/hooks/scaffold-eth/useTargetNetwork"; -/** - * Site footer - */ export const Footer = () => { - const { targetNetwork } = useTargetNetwork(); - const isLocalNetwork = targetNetwork.id === hardhat.id; - - return ( -
-
- -
-
- ); + return
; }; diff --git a/packages/nextjs/components/FrameEditor.tsx b/packages/nextjs/components/FrameEditor.tsx index b006b43..cc350af 100644 --- a/packages/nextjs/components/FrameEditor.tsx +++ b/packages/nextjs/components/FrameEditor.tsx @@ -9,7 +9,7 @@ const FrameEditor = () => { const [imageUrlOption, setImageUrlOption] = useState("url"); if (!currentFrame) return null; return ( -
+
diff --git a/packages/nextjs/components/FrameRenderer.tsx b/packages/nextjs/components/FrameRenderer.tsx index 7db2cfb..9ac5254 100644 --- a/packages/nextjs/components/FrameRenderer.tsx +++ b/packages/nextjs/components/FrameRenderer.tsx @@ -32,19 +32,17 @@ function FrameRender() { gap: "4px", }} > - {currentFrame.buttons?.map(({ label, action }, index: number) => ( + {currentFrame.buttons?.map(({ label }, index: number) => ( ))}
diff --git a/packages/nextjs/components/FramesSidebar.tsx b/packages/nextjs/components/FramesSidebar.tsx index 839cb21..5bb8e9f 100644 --- a/packages/nextjs/components/FramesSidebar.tsx +++ b/packages/nextjs/components/FramesSidebar.tsx @@ -1,10 +1,12 @@ -import { useEffect, useMemo, useState } from "react"; +import { useEffect, useState } from "react"; +import { DEFAULT_FRAME } from "~~/constants"; import { useProductJourney } from "~~/providers/ProductProvider"; import { getFrameById } from "~~/services/frames"; import { Frame } from "~~/types/commontypes"; function FrameSidebar() { - const { frames: dbFrames } = useProductJourney(); + const [currentFrameId, setCurrentFrameId] = useState(""); + const { frames: dbFrames, setFrame, setCurrentFrame, createFrame } = useProductJourney(); const [frames, setFrames] = useState(undefined); useEffect(() => { if (dbFrames) { @@ -13,16 +15,37 @@ function FrameSidebar() { .catch(error => console.error("Error fetching frames:", error)); } }, [dbFrames]); + const onCreate = async () => { + await createFrame.mutateAsync({ + name: "Frame", + frameJson: DEFAULT_FRAME, + }); + }; if (!frames) return null; return ( -
- {frames.map((frame, index) => ( -
-

{frame.name}

- {/* eslint-disable-next-line @next/next/no-img-element */} - {frame.name} -
- ))} +
+
+ {frames.map((frame, index) => ( +
{ + setCurrentFrameId(frame._id as string); + setFrame(frame); + setCurrentFrame(frame.frameJson); + }} + > +

{frame.name}

+ {/* eslint-disable-next-line @next/next/no-img-element */} + {frame.name} +
+ ))} +
+
+ +
); } diff --git a/packages/nextjs/providers/ProductProvider.tsx b/packages/nextjs/providers/ProductProvider.tsx index f66df21..f0f529b 100644 --- a/packages/nextjs/providers/ProductProvider.tsx +++ b/packages/nextjs/providers/ProductProvider.tsx @@ -2,7 +2,6 @@ import { PropsWithChildren, createContext, useContext, useEffect, useMemo, useSt import { useParams } from "next/navigation"; import { FrameMetadataType } from "@coinbase/onchainkit"; import { UseMutationResult, UseQueryResult, useMutation, useQuery } from "@tanstack/react-query"; -import { DEFAULT_FRAME } from "~~/constants"; import { getFrameById } from "~~/services/frames"; import { Frame, Journey } from "~~/types/commontypes"; @@ -16,6 +15,9 @@ interface IProductJourney { frames: string[] | undefined; setCurrentFrame: (frame: FrameMetadataType) => void; currentFrame: FrameMetadataType | null; + createFrame: UseMutationResult>; + saveFrame: UseMutationResult; + deleteFrame: UseMutationResult; } const ProductJourney = createContext(null); @@ -26,15 +28,8 @@ const useProduct = () => { return params.productID as string; }, [params.productID]); const [journey, setJourney] = useState(null); - const [frame, setFrame] = useState({ - _id: "", - name: "", - frameJson: DEFAULT_FRAME, - }); + const [frame, setFrame] = useState(null); const [currentFrame, setCurrentFrame] = useState(null); - const frames = useMemo(() => { - return journey?.frames; - }, [journey]); const productQuery = useQuery({ queryKey: ["product", productID], @@ -60,22 +55,99 @@ const useProduct = () => { if (!response.ok) { throw new Error("Network response was not ok"); } - return response.json(); + const data = await response.json(); + return data; }, onSuccess: () => { productQuery.refetch(); }, + onSettled: data => { + setJourney(data); + }, }); useEffect(() => { if (!productQuery.data) return; setJourney(productQuery.data); - console.log(productQuery.data); + if (frame || !productQuery.data.frames) return; getFrameById(productQuery.data.frames[0]).then(frame => { setFrame(frame); setCurrentFrame(frame.frameJson); }); - }, [productQuery.data]); + }, [frame, productQuery.data]); + + const createFrame = useMutation({ + mutationFn: async (frame: Omit) => { + const response = await fetch(`/api/frame`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(frame), + }); + if (!response.ok) { + throw new Error("Network response was not ok"); + } + const data = await response.json(); + return data; + }, + onSettled: data => { + console.log(data); + journey?.frames.push(data._id); + updateProduct.mutateAsync(journey as Journey); + setFrame(data); + setCurrentFrame(data.frameJson); + }, + }); + + const saveFrame = useMutation({ + mutationFn: async (frame: Frame) => { + const response = await fetch(`/api/frame/${frame._id}`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(frame), + }); + if (!response.ok) { + throw new Error("Network response was not ok"); + } + const data = await response.json(); + return data; + }, + onSettled: data => { + setFrame(data); + setCurrentFrame(data.frameJson); + productQuery.refetch(); + }, + }); + + const deleteFrame = useMutation({ + mutationFn: async (frame: Frame) => { + const response = await fetch(`/api/frame/${frame._id}`, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + }); + if (!response.ok) { + throw new Error("Network response was not ok"); + } + const newFrames = journey?.frames.filter(f => f !== frame._id); + if (!newFrames || !journey) return; + journey.frames = newFrames; + await updateProduct.mutateAsync(journey); + const data = await response.json(); + return data; + }, + onSettled: () => { + console.log("Frame deleted"); + }, + }); + const frames = useMemo(() => { + if (!journey) return; + return journey?.frames; + }, [journey]); return { productID, @@ -87,12 +159,15 @@ const useProduct = () => { setCurrentFrame, journey, frames, + createFrame, + saveFrame, + deleteFrame, }; }; export function ProvideProduct({ children }: PropsWithChildren) { const value = useProduct(); - return {children}; + return {children}; } export const useProductJourney = () => {