Merge pull request 'fix: testimonials from dynamic pages' (#4) from dev into main
Reviewed-on: #4
This commit is contained in:
commit
fece469f09
@ -9,6 +9,7 @@
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint",
|
||||
"payload": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload",
|
||||
"payload:generate:types": "payload generate:types",
|
||||
"tsc": "tsc"
|
||||
},
|
||||
@ -65,4 +66,4 @@
|
||||
"typescript": "^5"
|
||||
},
|
||||
"packageManager": "yarn@4.6.0"
|
||||
}
|
||||
}
|
@ -16,13 +16,13 @@ export default function NotFound() {
|
||||
<div className="row">
|
||||
<div className="col-sm-10 offset-sm-1 col-md-8 offset-md-2 col-lg-6 offset-lg-3">
|
||||
<div className="hs-wrap">
|
||||
<div className="wow fadeInUp" data-wow-delay=".1s">
|
||||
<div>
|
||||
<h1 className="hs-title-12 mb-40 mb-sm-30">404</h1>
|
||||
</div>
|
||||
<div className="mb-40 mb-sm-30 wow fadeInUp" data-wow-delay=".2s">
|
||||
<div className="mb-40 mb-sm-30">
|
||||
<h2 className="section-descr mb-20">The page you were looking for could not be found.</h2>
|
||||
</div>
|
||||
<div className="local-scroll wow fadeInUp" data-wow-delay=".3s">
|
||||
<div className="local-scroll">
|
||||
<Link href={`/`} className="btn btn-mod btn-w btn-round btn-medium btn-hover-anim">
|
||||
<i className="mi-arrow-left align-center mr-5" />
|
||||
<span>Back To Home Page</span>
|
||||
|
@ -1,38 +0,0 @@
|
||||
import { BeforeFooterBlock } from "@/components/Blocks/BeforeFooter";
|
||||
import { GoogleReviewsBlock } from "@/components/Blocks/GoogleReviews";
|
||||
import { GoogleReviewsSkeleton } from "@/components/Blocks/GoogleReviews/GoogleReviews";
|
||||
import Image from "next/image";
|
||||
import { Suspense } from "react";
|
||||
|
||||
export const metadata = {
|
||||
title: "Testimonials - Cochise Oncology",
|
||||
description: "Testimonials - Cochise Oncology",
|
||||
};
|
||||
|
||||
export default async function TestimonialsPage() {
|
||||
return (
|
||||
<>
|
||||
<section className="page-section bg-dark-1 bg-gradient-gray-dark-1 light-content bg-scroll overflow-hidden">
|
||||
{/* <!-- Background Shape --> */}
|
||||
<div className="absolute top-0 left-0 w-full h-full opacity-20">
|
||||
<Image src="/assets/images/hero-default.webp" width="0" height="0" sizes="100vw" className="w-full" alt="" />
|
||||
</div>
|
||||
{/* <!-- End Background Shape --> */}
|
||||
|
||||
<div className="container position-relative pt-sm-40 text-center">
|
||||
<div className="row">
|
||||
<div className="col-md-10 offset-md-1 col-lg-8 offset-lg-2">
|
||||
<h1 className="hs-title-10 mb-10">Testimonials</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section className="page-section scrollSpysection" id="testimonials">
|
||||
<Suspense fallback={<GoogleReviewsSkeleton />}>
|
||||
<GoogleReviewsBlock />
|
||||
</Suspense>
|
||||
</section>
|
||||
<BeforeFooterBlock />
|
||||
</>
|
||||
);
|
||||
}
|
7
src/blocks/GoogleReview.ts
Normal file
7
src/blocks/GoogleReview.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { Block } from "payload";
|
||||
|
||||
export const GoogleReviewBlock: Block = {
|
||||
slug: "googleReviewBlock",
|
||||
labels: { plural: "Google Reviews", singular: "Google Reviews" },
|
||||
fields: [],
|
||||
};
|
@ -1,6 +1,7 @@
|
||||
import { BeforeFooterBlock } from "@/blocks/BeforeFooter";
|
||||
import { BoxMenuGridBlock } from "@/blocks/BoxMenuGrid";
|
||||
import { ContentBlock } from "@/blocks/Content";
|
||||
import { GoogleReviewBlock } from "@/blocks/GoogleReview";
|
||||
import { HorizontalImageContentBlock } from "@/blocks/HorizontalImageContent";
|
||||
import { ImageSliderBlock } from "@/blocks/ImageSlider";
|
||||
import { OurTeamBlock } from "@/blocks/OurTeam";
|
||||
@ -45,6 +46,7 @@ export const Pages: CollectionConfig = {
|
||||
HorizontalImageContentBlock,
|
||||
ImageSliderBlock,
|
||||
BoxMenuGridBlock,
|
||||
GoogleReviewBlock,
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -1,51 +1,6 @@
|
||||
import { fetchGoogleReviews } from "@/services/payload/google-reviews";
|
||||
import { GoogleReviewProps, GoogleReviews } from "./GoogleReviews";
|
||||
|
||||
// const data: CardStarRatingProps["data"][] = [
|
||||
// {
|
||||
// star: 5,
|
||||
// description:
|
||||
// "Today i did my cat scan , and met Raymond, he radiates hope and good will, i then met Larry who showed me the hospitality suite, i was overwhelmed by thier kindness, every one i have met so far has been truly amazing.while at physical therapy the doc said i had made a wise",
|
||||
// },
|
||||
// {
|
||||
// star: 5,
|
||||
// description: "Great and caring service. Completely satisfied.",
|
||||
// },
|
||||
// {
|
||||
// star: 5,
|
||||
// description: "Sincere and caring attitude...very professional and inspires confidence.",
|
||||
// },
|
||||
// {
|
||||
// star: 5,
|
||||
// description:
|
||||
// "I've been going to cochise oncology for many years and everyone is always professional and take the time to explain everything",
|
||||
// },
|
||||
// {
|
||||
// star: 5,
|
||||
// description: "One fine person\n Very concerning. Glad to see her",
|
||||
// },
|
||||
// {
|
||||
// star: 5,
|
||||
// description:
|
||||
// "Barbara was very professional and friendly. She shared all info with me and gave me a copy of my lab results.",
|
||||
// },
|
||||
// {
|
||||
// star: 5,
|
||||
// description:
|
||||
// "Barbara is great! She listens and ask questions on other issues outside her area just to be sure you’re well taken care of.",
|
||||
// },
|
||||
// {
|
||||
// star: 5,
|
||||
// description:
|
||||
// "Today, at Cochise Oncology, I had an appointment with Dr. Reid Culton. He explained in great detail from the medical chart of the blood work and listen to my concerns. Dr. Reid Culton also answered my questions in great detail. Thank you.",
|
||||
// },
|
||||
// {
|
||||
// star: 5,
|
||||
// description:
|
||||
// "I absolutely love the people that work at this place. From the front desk to radiation room. Everyone is loving and caring.",
|
||||
// },
|
||||
// ];
|
||||
|
||||
export async function GoogleReviewsBlock() {
|
||||
const data = await fetchGoogleReviews();
|
||||
if (!data?.id) return <></>;
|
||||
|
@ -8,7 +8,7 @@ export interface HorizontalImageContentBlockProps {
|
||||
|
||||
export function HorizontalImageContentBlock({ img, content }: HorizontalImageContentBlockProps) {
|
||||
return (
|
||||
<div className="container mb-10">
|
||||
<div className="container">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-3 md:gap-5">
|
||||
<div>
|
||||
<Image src={img.url} width={0} height={0} sizes="100vw" className="w-full h-auto" alt={img.alt} />
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Fragment } from "react";
|
||||
import React, { Fragment, Suspense } from "react";
|
||||
|
||||
import type { Page } from "@/payload-types";
|
||||
import { ContentBlock } from "./Content";
|
||||
@ -7,6 +7,8 @@ import { OurTeamBlock } from "./OurTeam";
|
||||
import { HorizontalImageContentBlock } from "./HorizontalImageContent";
|
||||
import { ImageSliderBlock } from "./ImageSlider";
|
||||
import { BoxMenuGridBlock } from "./BoxMenuGrid";
|
||||
import { GoogleReviewsBlock } from "./GoogleReviews";
|
||||
import { GoogleReviewsSkeleton } from "./GoogleReviews/GoogleReviews";
|
||||
|
||||
const blockComponents = {
|
||||
contentBlock: ContentBlock,
|
||||
@ -15,6 +17,7 @@ const blockComponents = {
|
||||
horizontalImageContentBlock: HorizontalImageContentBlock,
|
||||
imageSliderBlock: ImageSliderBlock,
|
||||
boxMenuGridBlock: BoxMenuGridBlock,
|
||||
googleReviewBlock: GoogleReviewsBlock,
|
||||
};
|
||||
|
||||
export const RenderBlocks: React.FC<{
|
||||
@ -32,10 +35,26 @@ export const RenderBlocks: React.FC<{
|
||||
|
||||
if (blockType && blockType in blockComponents) {
|
||||
const Block = blockComponents[blockType];
|
||||
if (!Block) return null;
|
||||
|
||||
if (Block) {
|
||||
if (blockType === "googleReviewBlock") {
|
||||
return (
|
||||
<div className="my-16" key={index}>
|
||||
<Suspense fallback={<GoogleReviewsSkeleton />}>
|
||||
<GoogleReviewsBlock />
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
} else if (blockType === "beforeFooterBlock") {
|
||||
return (
|
||||
<div className="mt-16" key={index}>
|
||||
{/* @ts-ignore */}
|
||||
<BeforeFooterBlock {...block} />
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className="my-16" key={index}>
|
||||
{/* @ts-ignore */}
|
||||
<Block {...block} disableInnerContainer />
|
||||
</div>
|
||||
|
@ -1,115 +0,0 @@
|
||||
"use client";
|
||||
import BrandsDark from "./BrandsDark";
|
||||
import { numberItems4 } from "@/data/facts";
|
||||
import { testimonials5 } from "@/data/testimonials";
|
||||
|
||||
import { useEffect, useRef } from "react";
|
||||
import Image from "next/image";
|
||||
export default function TestimonialsDark() {
|
||||
const isotopContainer = useRef<any | null>(null);
|
||||
const initIsotop = async () => {
|
||||
const Isotope = (await import("isotope-layout")).default;
|
||||
const imagesloaded = (await import("imagesloaded")).default;
|
||||
|
||||
// Initialize Isotope in the mounted hook
|
||||
const isotope = new Isotope(isotopContainer.current, {
|
||||
itemSelector: ".col-md-6",
|
||||
layoutMode: "masonry", // or 'fitRows', depending on your layout needs
|
||||
});
|
||||
imagesloaded(isotopContainer.current).on(
|
||||
"progress",
|
||||
function () {
|
||||
// Trigger Isotope layout
|
||||
isotope.layout();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
/////////////////////////////////////////////////////
|
||||
// Magnate Animation
|
||||
|
||||
initIsotop();
|
||||
}, []);
|
||||
return (
|
||||
<div className="container position-relative">
|
||||
<div className="row">
|
||||
{/* Section Text */}
|
||||
<div className="col-lg-5 col-xl-5 d-flex align-items-center mb-md-60 mb-sm-40">
|
||||
<div className="w-100">
|
||||
<h2 className="section-caption-slick mb-30 mb-sm-20">
|
||||
Testimonials
|
||||
</h2>
|
||||
<h3 className="section-title mb-30">
|
||||
We're trusted by leading companies.
|
||||
</h3>
|
||||
<p className="section-descr mb-50 mb-sm-30">
|
||||
A static website stores a unique file for every page of a static
|
||||
website. Each time that page is requested, the same content is
|
||||
returned.
|
||||
</p>
|
||||
{/* Numbers */}
|
||||
<div className="row mt-sm-n10">
|
||||
{numberItems4.map((item: any, index: number) => (
|
||||
<div key={index} className="col-md-6 mt-sm-10">
|
||||
<div className="number-3-title">{item.title}</div>
|
||||
<div className="number-3-descr">{item.description}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{/* End Numbers */}
|
||||
</div>
|
||||
</div>
|
||||
{/* End Section Text */}
|
||||
{/* Testimonials Grid */}
|
||||
<div className="col-lg-7 col-xl-6 offset-xl-1 d-flex align-items-center">
|
||||
<div className="w-100 position-relative">
|
||||
<div
|
||||
ref={isotopContainer}
|
||||
className="row masonry mb-n30 wow fadeInUp"
|
||||
>
|
||||
{/* Testimonials Item */}
|
||||
{testimonials5.map((testimonial: any, index: number) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`col-md-6 mb-30 ${!index ? "mt-50 mt-sm-0" : ""} `}
|
||||
>
|
||||
<div className="testimonials-4-item">
|
||||
<div className="testimonials-4-icon">
|
||||
<i className="icon-quotation-mark" />
|
||||
</div>
|
||||
<blockquote className="testimonials-4-text">
|
||||
<p className="mb-0">{testimonial.text}</p>
|
||||
<footer className="testimonials-4-author mt-30 clearfix">
|
||||
<div className="testimonials-4-author-img float-start">
|
||||
<Image
|
||||
width={44}
|
||||
height={44}
|
||||
src={testimonial.imgSrc}
|
||||
alt={testimonial.altText}
|
||||
/>
|
||||
</div>
|
||||
<div className="overflow-hidden">
|
||||
{testimonial.author}
|
||||
<div className="small">{testimonial.position}</div>
|
||||
</div>
|
||||
</footer>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
{/* End Testimonials Item */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Testimonials Grid */}
|
||||
</div>
|
||||
{/* Logotypes */}
|
||||
<div className="page-section pb-0 text-center">
|
||||
<h3 className="section-title-tiny">Trusted by Leading Companies</h3>
|
||||
<BrandsDark />
|
||||
</div>
|
||||
{/* End Logotypes */}
|
||||
</div>
|
||||
);
|
||||
}
|
@ -262,6 +262,11 @@ export interface Page {
|
||||
blockName?: string | null;
|
||||
blockType: 'boxMenuGridBlock';
|
||||
}
|
||||
| {
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'googleReviewBlock';
|
||||
}
|
||||
)[]
|
||||
| null;
|
||||
meta?: {
|
||||
@ -678,6 +683,12 @@ export interface PagesSelect<T extends boolean = true> {
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
googleReviewBlock?:
|
||||
| T
|
||||
| {
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
};
|
||||
meta?:
|
||||
| T
|
||||
|
Loading…
x
Reference in New Issue
Block a user