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

This commit is contained in:
ArraysID
2025-05-10 08:54:45 +07:00
parent 13ab089afc
commit ff99564b05
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,
UsersIcon,
} from '@imphnen-frontend-service/shadcn-ui/atoms';
import { formatCMSImageDataToMedia } from 'apps/landing/src/lib/format';
import { HeroSection } from 'apps/landing/src/payload-types';
import { motion } from 'framer-motion';
import Image from 'next/image';
import { Fragment, useEffect, useState } from 'react';
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);
@@ -54,7 +63,7 @@ export function Hero(props: HeroSection) {
animate={{ opacity: 1, y: 0 }}
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" />
<span>{badgeText}</span>
</div>
@@ -124,13 +133,19 @@ export function Hero(props: HeroSection) {
</div>
<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" />
{(() => {
const media = formatCMSImageDataToMedia(heroImage);
if (!media) return null;
return (
<Image
src="/hero.jpeg"
src={media.url!}
alt={media.alt}
width={600}
height={500}
alt="IMPHNEN Programming Community"
className="w-full h-auto object-cover"
/>
);
})()}
</div>
</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 = {
'@payloadcms/storage-s3/client#S3ClientUploadHandler':
S3ClientUploadHandler_f97aa6c64367fa259c5bc0567239ef24,
};
"@payloadcms/storage-s3/client#S3ClientUploadHandler": S3ClientUploadHandler_f97aa6c64367fa259c5bc0567239ef24
}
@@ -4,6 +4,13 @@ export const HeroSection: GlobalConfig = {
slug: 'hero-section',
label: 'Hero Section',
fields: [
{
name: 'heroImage',
label: 'Hero Image',
type: 'upload',
relationTo: 'media',
required: true,
},
{
name: 'badgeText',
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 {
id: number;
heroImage: number | Media;
badgeText: string;
title: string;
highlight: string;
@@ -351,6 +352,7 @@ export interface CommunitiesSection {
* via the `definition` "hero-section_select".
*/
export interface HeroSectionSelect<T extends boolean = true> {
heroImage?: T;
badgeText?: T;
title?: T;
highlight?: T;