diff --git a/apps/dashboard/src/components/OgEditor.tsx b/apps/dashboard/src/components/OgEditor.tsx index d93a07a..9f67131 100644 --- a/apps/dashboard/src/components/OgEditor.tsx +++ b/apps/dashboard/src/components/OgEditor.tsx @@ -1,6 +1,7 @@ "use client"; import { useEffect, useRef } from "react"; import { Box, Flex } from "@radix-ui/themes"; +import { useRouter } from "next/navigation"; import type { OGElement } from "../lib/types"; import { createElementId } from "../lib/elements"; import { useZoomStore } from "../stores/zoomStore"; @@ -21,6 +22,7 @@ interface OgProviderProps { let elementIdToCopy: string | undefined; export function OgEditor({ imageId, width, height }: OgProviderProps) { + const router = useRouter(); const rootRef = useRef(null); const zoom = useZoomStore((state) => state.zoom); const { @@ -42,7 +44,11 @@ export function OgEditor({ imageId, width, height }: OgProviderProps) { * state, and load the elements and fonts. */ useEffect(() => { - loadImage(imageId); + // If the image doesn't exist, redirect to the images page + if (!loadImage(imageId)) { + router.push("/my-images"); + return; + } if (useImagesStore.persist.hasHydrated()) { setSelectedImageId(imageId); @@ -51,7 +57,7 @@ export function OgEditor({ imageId, width, height }: OgProviderProps) { useImagesStore.persist.onFinishHydration(() => { setSelectedImageId(imageId); }); - }, [imageId, loadImage, setSelectedImageId]); + }, [imageId, loadImage, router, setSelectedImageId]); useEffect(() => { function onClick(event: MouseEvent) { diff --git a/apps/dashboard/src/lib/__tests__/__snapshots__/export.test.ts.snap b/apps/dashboard/src/lib/__tests__/__snapshots__/export.test.ts.snap index 9ffb8ce..c126b5b 100644 --- a/apps/dashboard/src/lib/__tests__/__snapshots__/export.test.ts.snap +++ b/apps/dashboard/src/lib/__tests__/__snapshots__/export.test.ts.snap @@ -4609,4 +4609,4 @@ Uint8Array [ ] `; -exports[`renderToImg > should render to a base64 data url 1`] = `"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgaGVpZ2h0PSI2MzAiIHZpZXdCb3g9IjAgMCAxMjAwIDYzMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48bWFzayBpZD0ic2F0b3JpX29tLWlkIj48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTIwMCIgaGVpZ2h0PSI2MzAiIGZpbGw9IiNmZmYiLz48L21hc2s+PG1hc2sgaWQ9InNhdG9yaV9vbS1pZC0wIj48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjUwIiBmaWxsPSIjZmZmIi8+PC9tYXNrPjxwYXRoIGZpbGw9InJnYmEoMCwgMCwgMCwgMSkiIGQ9Ik0xMy44IDkuM0wyLjQgOS4zTDIuNCA1LjRMMjkuNyA1LjRMMjkuNyA5LjNMMTguMyA5LjNMMTguMyA0MS44TDEzLjggNDEuOEwxMy44IDkuM1pNNDMuNCA0Mi4zTDQzLjQgNDIuM1EzOS41IDQyLjMgMzYuNiA0MC42UTMzLjggMzguOCAzMi4yIDM1LjdRMzAuNyAzMi41IDMwLjcgMjguM1EzMC43IDI0LjEgMzIuMiAyMC45UTMzLjggMTcuNyAzNi41IDE1LjlRMzkuMyAxNC4xIDQzLjAgMTQuMUw0My4wIDE0LjFRNDUuMSAxNC4xIDQ3LjIgMTQuOFE0OS4zIDE1LjYgNTEuMCAxNy4xUTUyLjcgMTguNyA1My43IDIxLjNRNTQuNyAyMy45IDU0LjcgMjcuOEw1NC43IDI3LjhMNTQuNyAyOS41TDM0LjkgMjkuNVEzNS4wIDMyLjMgMzYuMCAzNC4yTDM2LjAgMzQuMlEzNy4wIDM2LjMgMzguOSAzNy41UTQwLjkgMzguNiA0My40IDM4LjZMNDMuNCAzOC42UTQ1LjAgMzguNiA0Ni40IDM4LjFRNDcuNyAzNy42IDQ4LjcgMzYuN1E0OS43IDM1LjcgNTAuMiAzNC4zTDUwLjIgMzQuM0w1NC4zIDM1LjRRNTMuNiAzNy41IDUyLjEgMzkuMFE1MC42IDQwLjYgNDguNCA0MS41UTQ2LjIgNDIuMyA0My40IDQyLjNaTTM0LjkgMjUuOUwzNC45IDI1LjlMNTAuNCAyNS45UTUwLjQgMjMuNiA0OS41IDIxLjhRNDguNiAyMC4wIDQ2LjkgMTguOVE0NS4yIDE3LjkgNDMuMCAxNy45TDQzLjAgMTcuOVE0MC41IDE3LjkgMzguNiAxOS4xUTM2LjggMjAuNCAzNS44IDIyLjNMMzUuOCAyMi4zUTM1LjAgMjQuMCAzNC45IDI1LjlaTTU4LjcgMTQuNUw2My41IDE0LjVMNzAuMCAyNS42TDc2LjYgMTQuNUw4MS40IDE0LjVMNzIuNiAyOC4xTDgxLjQgNDEuOEw3Ni42IDQxLjhMNzAuMCAzMS4yTDYzLjUgNDEuOEw1OC43IDQxLjhMNjcuMyAyOC4xTDU4LjcgMTQuNVpNOTMuNCAxNC41TDk5LjIgMTQuNUw5OS4yIDE4LjBMOTMuNCAxOC4wTDkzLjQgMzMuOVE5My40IDM1LjcgOTMuOSAzNi42UTk0LjQgMzcuNSA5NS4zIDM3LjhROTYuMSAzOC4xIDk3LjAgMzguMUw5Ny4wIDM4LjFROTcuNyAzOC4xIDk4LjIgMzguMFE5OC42IDM3LjkgOTguOSAzNy45TDk4LjkgMzcuOUw5OS43IDQxLjZROTkuMyA0MS44IDk4LjUgNDEuOVE5Ny44IDQyLjEgOTYuNiA0Mi4xTDk2LjYgNDIuMVE5NC44IDQyLjEgOTMuMSA0MS4zUTkxLjQgNDAuNiA5MC4zIDM5LjBRODkuMiAzNy41IDg5LjIgMzUuMUw4OS4yIDM1LjFMODkuMiAxOC4wTDg1LjEgMTguMEw4NS4xIDE0LjVMODkuMiAxNC41TDg5LjIgOC4wTDkzLjQgOC4wTDkzLjQgMTQuNVogIi8+PC9zdmc+"`; +exports[`renderToImg > should render to a base64 data url 1`] = `"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgaGVpZ2h0PSI2MzAiIHZpZXdCb3g9IjAgMCAxMjAwIDYzMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48bWFzayBpZD0ic2F0b3JpX29tLWlkIj48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTIwMCIgaGVpZ2h0PSI2MzAiIGZpbGw9IiNmZmYiLz48L21hc2s+PG1hc2sgaWQ9InNhdG9yaV9vbS1pZC0wIj48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjUwIiBmaWxsPSIjZmZmIi8+PC9tYXNrPjxwYXRoIGZpbGw9InJnYmEoMCwgMCwgMCwgMSkiIGQ9Ik0xMy44IDEyLjZMMi40IDEyLjZMMi40IDguNUwyOS45IDguNUwyOS45IDEyLjZMMTguNSAxMi42TDE4LjUgNDQuOUwxMy44IDQ0LjlMMTMuOCAxMi42Wk00Ny42IDQ1LjVMNDcuNiA0NS41UTQzLjcgNDUuNSA0MC44IDQzLjdRMzcuOSA0MS45IDM2LjQgMzguOFEzNC44IDM1LjYgMzQuOCAzMS40UTM0LjggMjcuMiAzNi4zIDI0LjBRMzcuOCAyMC44IDQwLjYgMTkuMFE0My40IDE3LjIgNDcuMSAxNy4yTDQ3LjEgMTcuMlE0OS4zIDE3LjIgNTEuNCAxOC4wUTUzLjUgMTguNyA1NS4yIDIwLjNRNTYuOSAyMS45IDU4LjAgMjQuNVE1OS4wIDI3LjEgNTkuMCAzMC45TDU5LjAgMzAuOUw1OS4wIDMyLjdMMzkuMyAzMi43UTM5LjQgMzUuMyA0MC4zIDM3LjNMNDAuMyAzNy4zUTQxLjQgMzkuNCA0My4yIDQwLjVRNDUuMSA0MS41IDQ3LjYgNDEuNUw0Ny42IDQxLjVRNDkuMiA0MS41IDUwLjYgNDEuMVE1MS45IDQwLjYgNTIuOCAzOS43UTUzLjggMzguNyA1NC4zIDM3LjRMNTQuMyAzNy40TDU4LjUgMzguNVE1Ny45IDQwLjYgNTYuNCA0Mi4xUTU0LjkgNDMuNyA1Mi42IDQ0LjZRNTAuNCA0NS41IDQ3LjYgNDUuNVpNMzkuMyAyOS4wTDM5LjMgMjkuMEw1NC41IDI5LjBRNTQuMyAyNy4xIDUzLjcgMjUuNkw1My43IDI1LjZRNTIuOSAyMy41IDUxLjIgMjIuM1E0OS42IDIxLjEgNDcuMSAyMS4xUTQ0LjYgMjEuMSA0Mi45IDIyLjNRNDEuMSAyMy42IDQwLjIgMjUuNUw0MC4yIDI1LjVRMzkuNCAyNy4xIDM5LjMgMjkuMFpNNjguMSA0NC45TDYzLjAgNDQuOUw3Mi42IDMwLjlMNjMuNiAxNy42TDY4LjcgMTcuNkw3Mi4xIDIyLjlRNzMuNCAyNC45IDc0LjQgMjYuN0w3NC40IDI2LjdRNzQuOCAyNy41IDc1LjIgMjguMkw3NS4yIDI4LjJRNzUuNiAyNy41IDc2LjAgMjYuN0w3Ni4wIDI2LjdRNzYuOSAyNC45IDc4LjIgMjIuOUw3OC4yIDIyLjlMODEuNyAxNy42TDg2LjcgMTcuNkw3Ny42IDMxLjFMODcuMSA0NC45TDgyLjAgNDQuOUw3OC4wIDM4LjdRNzYuNyAzNi43IDc1LjggMzUuMEw3NS44IDM1LjBRNzUuNCAzNC4zIDc1LjAgMzMuN0w3NS4wIDMzLjdRNzQuNyAzNC4zIDc0LjMgMzUuMEw3NC4zIDM1LjBRNzMuNSAzNi43IDcyLjEgMzguN0w3Mi4xIDM4LjdMNjguMSA0NC45Wk05Ny43IDE3LjZMMTAzLjMgMTcuNkwxMDMuMyAyMS4zTDk3LjcgMjEuM0w5Ny43IDM3LjhROTcuNyAzOS42IDk4LjQgNDAuNVE5OS4yIDQxLjMgMTAwLjkgNDEuM0wxMDAuOSA0MS4zUTEwMS4zIDQxLjMgMTAyLjAgNDEuMlExMDIuNiA0MS4xIDEwMy4yIDQxLjBMMTAzLjIgNDEuMEwxMDQuMSA0NC43UTEwMy40IDQ1LjAgMTAyLjUgNDUuMVExMDEuNyA0NS4yIDEwMC44IDQ1LjJMMTAwLjggNDUuMlE5Ny4zIDQ1LjIgOTUuMyA0My4zUTkzLjMgNDEuNSA5My4zIDM4LjFMOTMuMyAzOC4xTDkzLjMgMjEuM0w4OS4yIDIxLjNMODkuMiAxNy42TDkzLjMgMTcuNkw5My4zIDExLjFMOTcuNyAxMS4xTDk3LjcgMTcuNlogIi8+PC9zdmc+"`; diff --git a/apps/dashboard/src/stores/elementsStore.ts b/apps/dashboard/src/stores/elementsStore.ts index 6fd9ffb..74de8ca 100644 --- a/apps/dashboard/src/stores/elementsStore.ts +++ b/apps/dashboard/src/stores/elementsStore.ts @@ -7,7 +7,7 @@ interface ElementsState { imageId: string; elements: OGElement[]; setElements: (elements: OGElement[]) => void; - loadImage: (imageId: string) => void; + loadImage: (imageId: string) => boolean; selectedElementId: string | null; setSelectedElementId: (id: string | null) => void; addElement: (element: OGElement) => void; @@ -24,10 +24,12 @@ export const useElementsStore = create()( set({ elements }); }, loadImage: (imageId) => { - const elements = JSON.parse( - localStorage.getItem(imageId) ?? "[]", - ) as OGElement[]; + const item = localStorage.getItem(imageId); + if (!item && imageId !== "splash") { + return false; + } + const elements = JSON.parse(item ?? "[]") as OGElement[]; set({ imageId, elements, selectedElementId: null }); // Immediately load fonts for elements that will be visible on the page. @@ -38,6 +40,7 @@ export const useElementsStore = create()( }); useElementsStore.temporal.getState().clear(); + return true; }, selectedElementId: null, setSelectedElementId: (id) => {