feat: add heroImage field to HeroSection and implement image formatting utility

This commit is contained in:
ArraysID
2025-05-11 05:24:31 +07:00
parent 1f9aa2e6b3
commit 33d750b221
6 changed files with 46 additions and 13 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

@@ -6,13 +6,22 @@ import {
SparklesIcon, SparklesIcon,
UsersIcon, UsersIcon,
} from '@imphnen-frontend-service/shadcn-ui/atoms'; } from '@imphnen-frontend-service/shadcn-ui/atoms';
import { formatCMSImageDataToMedia } from 'apps/landing/src/lib/format';
import { HeroSection } from 'apps/landing/src/payload-types'; import { HeroSection } from 'apps/landing/src/payload-types';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import Image from 'next/image'; import Image from 'next/image';
import { Fragment, useEffect, useState } from 'react'; import { Fragment, useEffect, useState } from 'react';
export function Hero(props: HeroSection) { export function Hero(props: HeroSection) {
const { badgeText, buttons, description, highlight, title, stats } = props; const {
badgeText,
buttons,
description,
highlight,
title,
stats,
heroImage,
} = props;
const [scrollY, setScrollY] = useState(0); const [scrollY, setScrollY] = useState(0);
@@ -54,7 +63,7 @@ export function Hero(props: HeroSection) {
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }} transition={{ duration: 0.5 }}
> >
<div className="inline-flex items-center rounded-full border px-3 py-1 text-sm"> <div className="inline-flex items-center rounded-full border px-3 py-1 text-sm w-fit">
<SparklesIcon className="mr-1 h-3.5 w-3.5 text-primary" /> <SparklesIcon className="mr-1 h-3.5 w-3.5 text-primary" />
<span>{badgeText}</span> <span>{badgeText}</span>
</div> </div>
@@ -125,13 +134,19 @@ font-bold text-black hover:text-white cursor-pointer"
</div> </div>
<div className="relative z-10 rounded-2xl overflow-hidden border shadow-2xl"> <div className="relative z-10 rounded-2xl overflow-hidden border shadow-2xl">
<div className="absolute inset-0 bg-gradient-to-tr from-primary/10 to-blue-400/10" /> <div className="absolute inset-0 bg-gradient-to-tr from-primary/10 to-blue-400/10" />
<Image {(() => {
src="/hero.jpeg" const media = formatCMSImageDataToMedia(heroImage);
width={600} if (!media) return null;
height={500} return (
alt="IMPHNEN Programming Community" <Image
className="w-full h-auto object-cover" src={media.url!}
/> alt={media.alt}
width={600}
height={500}
className="w-full h-auto object-cover"
/>
);
})()}
</div> </div>
</div> </div>
</motion.div> </motion.div>
@@ -1,6 +1,5 @@
import { S3ClientUploadHandler as S3ClientUploadHandler_f97aa6c64367fa259c5bc0567239ef24 } from '@payloadcms/storage-s3/client'; import { S3ClientUploadHandler as S3ClientUploadHandler_f97aa6c64367fa259c5bc0567239ef24 } from '@payloadcms/storage-s3/client'
export const importMap = { export const importMap = {
'@payloadcms/storage-s3/client#S3ClientUploadHandler': "@payloadcms/storage-s3/client#S3ClientUploadHandler": S3ClientUploadHandler_f97aa6c64367fa259c5bc0567239ef24
S3ClientUploadHandler_f97aa6c64367fa259c5bc0567239ef24, }
};
@@ -4,6 +4,13 @@ export const HeroSection: GlobalConfig = {
slug: 'hero-section', slug: 'hero-section',
label: 'Hero Section', label: 'Hero Section',
fields: [ fields: [
{
name: 'heroImage',
label: 'Hero Image',
type: 'upload',
relationTo: 'media',
required: true,
},
{ {
name: 'badgeText', name: 'badgeText',
label: 'Badge Text', label: 'Badge Text',
+10
View File
@@ -0,0 +1,10 @@
import { Media } from '../payload-types';
export function formatCMSImageDataToMedia(
image: number | Media | null | undefined
): Media | null {
if (image && typeof image === 'object' && 'url' in image) {
return image as Media;
}
return null;
}
+2
View File
@@ -285,6 +285,7 @@ export interface PayloadMigrationsSelect<T extends boolean = true> {
*/ */
export interface HeroSection { export interface HeroSection {
id: number; id: number;
heroImage: number | Media;
badgeText: string; badgeText: string;
title: string; title: string;
highlight: string; highlight: string;
@@ -351,6 +352,7 @@ export interface CommunitiesSection {
* via the `definition` "hero-section_select". * via the `definition` "hero-section_select".
*/ */
export interface HeroSectionSelect<T extends boolean = true> { export interface HeroSectionSelect<T extends boolean = true> {
heroImage?: T;
badgeText?: T; badgeText?: T;
title?: T; title?: T;
highlight?: T; highlight?: T;