feat: add heroImage field to HeroSection and implement image formatting utility
This commit is contained in:
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',
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user