From 86dd453c85450591b70e489fb96016e778e5a02f Mon Sep 17 00:00:00 2001 From: Christel Westerberg Date: Thu, 8 Feb 2024 16:04:47 +0100 Subject: [PATCH] fix: add loading state when no uri is given --- app/[lang]/(preview)/error.tsx | 9 ++ app/[lang]/(preview)/preview/page.tsx | 36 ++++---- components/Current/LivePreview/index.tsx | 7 +- components/Current/LoadingPreview/index.tsx | 22 +++++ .../Current/LoadingPreview/loading.module.css | 90 +++++++++++++++++++ middleware.ts | 23 ++--- 6 files changed, 153 insertions(+), 34 deletions(-) create mode 100644 app/[lang]/(preview)/error.tsx create mode 100644 components/Current/LoadingPreview/index.tsx create mode 100644 components/Current/LoadingPreview/loading.module.css diff --git a/app/[lang]/(preview)/error.tsx b/app/[lang]/(preview)/error.tsx new file mode 100644 index 000000000..4b2d7bb55 --- /dev/null +++ b/app/[lang]/(preview)/error.tsx @@ -0,0 +1,9 @@ +"use client" + +export default function Error({ error }: { error: Error }) { + return ( +
+

Something went wrong!

+
+ ) +} diff --git a/app/[lang]/(preview)/preview/page.tsx b/app/[lang]/(preview)/preview/page.tsx index 1f1a7e15d..1d63fdd34 100644 --- a/app/[lang]/(preview)/preview/page.tsx +++ b/app/[lang]/(preview)/preview/page.tsx @@ -1,35 +1,32 @@ -import { notFound } from "next/navigation"; +import { notFound } from "next/navigation" -import { previewRequest } from "@/lib/previewRequest"; -import { GetCurrentBlockPage } from "@/lib/graphql/Query/CurrentBlockPage.graphql"; +import { previewRequest } from "@/lib/previewRequest" +import { GetCurrentBlockPage } from "@/lib/graphql/Query/CurrentBlockPage.graphql" -import Aside from "@/components/Current/Aside"; -import Blocks from "@/components/Current/Blocks"; -import Header from "@/components/Current/Header"; -import Hero from "@/components/Current/Hero"; +import Aside from "@/components/Current/Aside" +import Blocks from "@/components/Current/Blocks" +import Header from "@/components/Current/Header" +import Hero from "@/components/Current/Hero" -import type { PageArgs, LangParams, UriParams } from "@/types/params"; -import type { GetCurrentBlockPageData } from "@/types/requests/currentBlockPage"; -import ContentstackLivePreview from "@contentstack/live-preview-utils"; +import type { PageArgs, LangParams, UriParams } from "@/types/params" +import type { GetCurrentBlockPageData } from "@/types/requests/currentBlockPage" +import ContentstackLivePreview from "@contentstack/live-preview-utils" +import LoadingPreview from "@/components/Current/LoadingPreview" export default async function CurrentContentPage({ params, searchParams, }: PageArgs) { try { - const livePreviewHash = searchParams["live_preview"] - if (!livePreviewHash) { - throw new Error("No hash found") - } ContentstackLivePreview.setConfigFromParams(searchParams) if (!searchParams.uri) { - throw new Error("Bad URI") + return } const response = await previewRequest( GetCurrentBlockPage, - { locale: params.lang, url: searchParams.uri } + { locale: params.lang, uid: searchParams.uri } ) if (!response.data?.all_current_blocks_page?.total) { @@ -53,8 +50,9 @@ export default async function CurrentContentPage({ ) - } catch (err) { - console.error(err) - return notFound(); + } catch (error) { + // TODO: throw 500 + console.error(error) + throw new Error("Something went wrong") } } diff --git a/components/Current/LivePreview/index.tsx b/components/Current/LivePreview/index.tsx index 78dab3f05..19d35eb39 100644 --- a/components/Current/LivePreview/index.tsx +++ b/components/Current/LivePreview/index.tsx @@ -1,13 +1,12 @@ "use client"; -import ContentstackLivePreview from "@contentstack/live-preview-utils"; -import { useEffect } from "react"; +import { useEffect } from "react" +import ContentstackLivePreview from "@contentstack/live-preview-utils" export default function InitLivePreview() { useEffect(() => { if (!ContentstackLivePreview.livePreview) { - console.log("INIT"); - ContentstackLivePreview.init(); + ContentstackLivePreview.init() } }, []); diff --git a/components/Current/LoadingPreview/index.tsx b/components/Current/LoadingPreview/index.tsx new file mode 100644 index 000000000..a8a20e784 --- /dev/null +++ b/components/Current/LoadingPreview/index.tsx @@ -0,0 +1,22 @@ +import styles from "./loading.module.css" + +export default function LoadingPreview() { + return ( +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ) +} diff --git a/components/Current/LoadingPreview/loading.module.css b/components/Current/LoadingPreview/loading.module.css new file mode 100644 index 000000000..50e63067c --- /dev/null +++ b/components/Current/LoadingPreview/loading.module.css @@ -0,0 +1,90 @@ +.container { + display: flex; + justify-content: center; + align-items: center; + height: 200px; +} + +.spinner { + display: inline-block; + position: relative; + width: 80px; + height: 80px; +} + +.spinner div { + transform-origin: 40px 40px; + animation: spinnerAnimation 1.2s linear infinite; +} + +.spinner div::after { + content: " "; + display: block; + position: absolute; + top: 3px; + left: 37px; + width: 6px; + height: 18px; + border-radius: 20%; + background: red; +} + +.spinner div:nth-child(1) { + transform: rotate(0deg); + animation-delay: -1.1s; +} + + .spinner div:nth-child(2) { + transform: rotate(30deg); + animation-delay: -1s; + } + .spinner div:nth-child(3) { + transform: rotate(60deg); + animation-delay: -0.9s; + } + .spinner div:nth-child(4) { + transform: rotate(90deg); + animation-delay: -0.8s; + } + .spinner div:nth-child(5) { + transform: rotate(120deg); + animation-delay: -0.7s; + } + .spinner div:nth-child(6) { + transform: rotate(150deg); + animation-delay: -0.6s; + } + .spinner div:nth-child(7) { + transform: rotate(180deg); + animation-delay: -0.5s; + } + .spinner div:nth-child(8) { + transform: rotate(210deg); + animation-delay: -0.4s; + } + .spinner div:nth-child(9) { + transform: rotate(240deg); + animation-delay: -0.3s; + } + .spinner div:nth-child(10) { + transform: rotate(270deg); + animation-delay: -0.2s; + } + .spinner div:nth-child(11) { + transform: rotate(300deg); + animation-delay: -0.1s; + } + .spinner div:nth-child(12) { + transform: rotate(330deg); + animation-delay: 0s; + } + + +@keyframes spinnerAnimation { + 0% { + opacity: 1; + } + 100% { + opacity: 0; + } +} \ No newline at end of file diff --git a/middleware.ts b/middleware.ts index f780705dc..760d15083 100644 --- a/middleware.ts +++ b/middleware.ts @@ -7,17 +7,17 @@ export async function middleware(request: NextRequest) { // const locales = await fetch(CMS_API, { // locales: true // }) - const locales = ["en", "sv", "no", "fi", "da", "de"]; + const locales = ["en", "sv", "no", "fi", "da", "de"] const locale = locales.find( (locale) => request.nextUrl.pathname.startsWith(`/${locale}/`) || request.nextUrl.pathname === `/${locale}` - ); + ) if (!locale) { //return - return Response.json("Not found!!!", { status: 404 }); + return Response.json("Not found!!!", { status: 404 }) } // const data = await fetch(CMS_API, { @@ -26,23 +26,24 @@ export async function middleware(request: NextRequest) { // }).json() //const contentType = data.response.meta.contentType; - const contentType = "currentContentPage"; + const contentType = "currentContentPage" const pathNameWithoutLocale = request.nextUrl.pathname.replace( `/${locale}`, "" - ); + ) - const searchParams = new URLSearchParams(request.nextUrl.searchParams); + const searchParams = new URLSearchParams(request.nextUrl.searchParams) if (request.nextUrl.pathname.includes("preview")) { - searchParams.set("uri", pathNameWithoutLocale.replace("/preview", "")); + searchParams.set("uri", pathNameWithoutLocale.replace("/preview", "")) return NextResponse.rewrite( new URL(`/${locale}/preview?${searchParams.toString()}`, request.url) - ); + ) } - searchParams.set("uri", pathNameWithoutLocale); + + searchParams.set("uri", pathNameWithoutLocale) switch (contentType) { case "currentContentPage": @@ -51,9 +52,9 @@ export async function middleware(request: NextRequest) { `/${locale}/current-content-page?${searchParams.toString()}`, request.url ) - ); + ) } - return NextResponse.redirect(new URL("/home", request.url)); + return NextResponse.redirect(new URL("/home", request.url)) } // See "Matching Paths" below to learn more