[yoga-15] improve service list rendering

This commit is contained in:
Schneider Roland 2025-09-08 22:21:56 +02:00
parent 6b316ec1aa
commit c0ca7108c7
7 changed files with 154 additions and 21 deletions

View File

@ -73,8 +73,8 @@ const generateIcons = ( ): IconDescriptor[] => {
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Yoga App", title: "Reverseyoga",
description: "Yoga App", description: "Reverseyoga - Yoga mindenkinek",
icons: generateIcons(), icons: generateIcons(),
manifest: "./assets/images/favicon/manifest.json", manifest: "./assets/images/favicon/manifest.json",
other: { other: {

View File

@ -20,9 +20,9 @@ export default async function Services() {
<> <>
<SubHeaderComponent header={{header1:header,description}} common={common}/> <SubHeaderComponent header={{header1:header,description}} common={common}/>
{ {
services && services.length > 0 && services.map( singleService => { services && services.length > 0 && services.map( (singleService,index) => {
return ( return (
<SingleServiceComponent key={singleService.id} config={singleService} /> <SingleServiceComponent key={singleService.id} config={singleService} index={index}/>
) )
}) })
} }

View File

@ -0,0 +1,35 @@
import {ButtonConfig, ImageConfig} from "@/types/types";
import {BlocksContent} from "@strapi/blocks-react-renderer";
import BlockWithRightImage from "@/components/block.with.right.image.component";
import BlockWithLeftImage from "@/components/block.with.left.image.component";
export interface BlockWithImageComponentProps {
id: number;
title?: string;
header?: string;
block: BlocksContent;
image: ImageConfig;
button?: ButtonConfig;
}
export default function BlockWithImageComponent({
block,
image,
id,
title,
header,
button
}: BlockWithImageComponentProps) {
return (
<>
{image?.position == 'Right' && <BlockWithRightImage
block={block} image={image} id={id} title={title}
header={header}
button={button}/>}
{image?.position == 'Left' && <BlockWithLeftImage block={block} image={image} id={id} title={title}
header={header}
button={button}/>}
</>
);
}

View File

@ -0,0 +1,42 @@
import YogaImageComponent from "@/components/yoga.image.component";
import NextBlocksRenderer from "@/components/next.blocks.renderer";
import {BlockWithImageComponentProps} from "@/components/block.with.image.component";
export default function BlockWithLeftImage ( {
title,header,image,block,button
} : BlockWithImageComponentProps){
return (
<section className="vision_section">
<div className="container">
<div className="vision_box">
<div className="row">
<div className="col-lg-6 col-md-6 col-sm-12 col-xs-12">
<div className="vision_image">
<figure className="mb-0"><YogaImageComponent src={image.url} alt="" className="img-fluid" /></figure>
</div>
</div>
<div className="col-lg-6 col-md-6 col-sm-12 col-xs-12" data-aos="fade-up">
<div className="vision_content">
<h5>{title}</h5>
<h2>{header}</h2>
<NextBlocksRenderer content={ block } />
<div className="btn_wrapper">
{button && <a href={button.link} className="text-decoration-none read_more_btn">{button.label}</a>}
</div>
</div>
</div>
</div>
</div>
<figure className="vision_left_shape left_shape mb-0">
<YogaImageComponent src="./assets/images/our_vision_shape.png" alt="" className="img-fluid" />
</figure>
</div>
</section>
)
}

View File

@ -0,0 +1,40 @@
import YogaImageComponent from "@/components/yoga.image.component";
import {BlockWithImageComponentProps} from "@/components/block.with.image.component";
import NextBlocksRenderer from "@/components/next.blocks.renderer";
export default function BlockWithRightImage ({
title,header, block,button, image: {
url,
} ,
}: BlockWithImageComponentProps){
return (
<section className="mission_section">
<div className="container">
<div className="mission_box">
<div className="row">
<div className="col-lg-6 col-md-6 col-sm-12 col-xs-12" data-aos="fade-up">
<div className="mission_content">
{title && <h5>{title}</h5>}
{header && <h2>{header}</h2>}
<NextBlocksRenderer content={ block } />
<div className="btn_wrapper">
{button && <a href={button.link} className="text-decoration-none read_more_btn">{button.label}</a>}
</div>
</div>
</div>
<div className="col-lg-6 col-md-6 col-sm-12 col-xs-12">
<div className="mission_image">
<figure className="mb-0"><YogaImageComponent src={url} alt="" className="img-fluid" /></figure>
</div>
</div>
</div>
</div>
<figure className="mission_right_shape right_shape mb-0">
<YogaImageComponent src="./assets/images/our_mission_shape.png" alt="" className="img-fluid" />
</figure>
</div>
</section>
)
}

View File

@ -1,31 +1,26 @@
import {YogaSingleService_Plain} from "@/types/generated-strapi-interfaces/api/yoga-single-service"; import {YogaSingleService_Plain} from "@/types/generated-strapi-interfaces/api/yoga-single-service";
import clsx from "clsx";
import NextBlocksRenderer from "@/components/next.blocks.renderer";
import {BlocksContent} from "@strapi/blocks-react-renderer";
import React from "react"; import React from "react";
import BlockWithImageComponent from "@/components/block.with.image.component";
import {ImagePosition, StrapiFile} from "@/types/types";
import strapiApi from "@/api/strapi/strapi-api";
export interface Props { export interface Props {
config: YogaSingleService_Plain config: YogaSingleService_Plain,
index: number
} }
const SingleService = ({config}: Props) => { const SingleService = ({config,index}: Props) => {
if (!config || !config.article) { if (!config || !config.article || !config.image) {
return null; // or some fallback UI return null; // or some fallback UI
} }
const {article, image, id, header } = config;
const strapiFile = image as StrapiFile;
const imageUrl = strapiApi.getImageUrl(strapiFile?.url);
return ( return (
<section id={config.name+""} className={clsx('mb-3')}> <BlockWithImageComponent id={id} block={article} image={{ position: index %2 ? ImagePosition.Left : ImagePosition.Right, url:imageUrl}} header={header} />
<div className="container">
<div className={"row"}>
<div className={"col-lg-12 col-md-12 col-sm-12 col-xs-12"}>
<NextBlocksRenderer
content={config.article as BlocksContent}
/>
</div>
</div>
</div>
</section>
); );
} }

View File

@ -1,3 +1,4 @@
export interface StrapiFile{ export interface StrapiFile{
"id": string, "id": string,
"documentId": string, "documentId": string,
@ -5,3 +6,23 @@ export interface StrapiFile{
"mime": string, "mime": string,
"url": string "url": string
} }
export enum ImagePosition {
Left = 'Left',
Right = 'Right',}
export interface ButtonConfig{
label?: string,
link?: string,
style?: 'Primary' | 'Secondary' | 'Outline' | 'Text',
size?: 'Small' | 'Medium' | 'Large',
openInNewTab?: boolean,
}
export interface ImageConfig{
position: ImagePosition,
url: string,
alt?: string,
width?: number,
height?: number,
}