diff --git a/next.config.ts b/next.config.ts index 4f2d549..ea73e8f 100644 --- a/next.config.ts +++ b/next.config.ts @@ -2,13 +2,14 @@ import { withPayload } from '@payloadcms/next/withPayload' import type { NextConfig } from 'next' import path from 'path' import { fileURLToPath } from 'url' - + const __filename = fileURLToPath(import.meta.url) const dirname = path.dirname(__filename) import { redirects } from './redirects' - + const NEXT_PUBLIC_SERVER_URL = process.env.NEXT_PUBLIC_SERVER_URL || 'http://localhost:3002' - +const S3_BUCKET_URL = process.env.NEXT_PUBLIC_S3_URL || '' + const nextConfig: NextConfig = { output: 'standalone', sassOptions: { @@ -20,14 +21,14 @@ const nextConfig: NextConfig = { pathname: '/api/media/file/**', }, ], - qualities: [100], + qualities: [25, 50, 75, 100], remotePatterns: [ - ...[NEXT_PUBLIC_SERVER_URL].map((item) => { + ...[NEXT_PUBLIC_SERVER_URL, S3_BUCKET_URL].filter(Boolean).map((item) => { const url = new URL(item) - return { hostname: url.hostname, protocol: url.protocol.replace(':', '') as 'http' | 'https', + pathname: '/**', } }), ], @@ -38,22 +39,21 @@ const nextConfig: NextConfig = { '.js': ['.ts', '.tsx', '.js', '.jsx'], '.mjs': ['.mts', '.mjs'], } - + const replaceHash = (val: unknown) => typeof val === 'string' ? val.replace('[chunkhash]', '[contenthash]') : val - + webpackConfig.output.filename = replaceHash(webpackConfig.output.filename) webpackConfig.output.chunkFilename = replaceHash(webpackConfig.output.chunkFilename) - + return webpackConfig }, - + reactStrictMode: true, redirects, turbopack: { root: path.resolve(dirname), }, } - + export default withPayload(nextConfig, { devBundleServerPackages: false }) - \ No newline at end of file diff --git a/src/blocks/Showcase/Component.tsx b/src/blocks/Showcase/Component.tsx index 7e73a7e..d8b1dce 100644 --- a/src/blocks/Showcase/Component.tsx +++ b/src/blocks/Showcase/Component.tsx @@ -1,15 +1,10 @@ import React from 'react' import Image from 'next/image' - -type MediaObject = { - url?: string - alt?: string - width?: number - height?: number -} +// Import the generated Media type from your Payload config +import type { Media as MediaType } from '@/payload-types' type ShowcaseItem = { - image?: MediaObject | null + image?: MediaType | null imageUrl?: string title: string description?: string @@ -23,39 +18,47 @@ type ShowcaseBlockProps = { items?: ShowcaseItem[] } -function ShowcaseImage(props: { item: ShowcaseItem }): React.ReactElement { - const item = props.item - const imageUrl = item.image != null && typeof item.image === 'object' ? item.image.url : null - const imageAlt = item.image != null && typeof item.image === 'object' ? item.image.alt : item.title +function ShowcaseImage({ item }: { item: ShowcaseItem }) { + // Payload 3.0 returns the object directly if depth is configured + const image = item.image - if (imageUrl != null && item.imageUrl != null) { - return ( - - href={item.imageUrl} - target="_blank" - rel="noopener noreferrer" - className="block relative w-full aspect-video overflow-hidden rounded-t-xl group" - > - {imageAlt + // Use the image object if available, otherwise fallback + if (image && typeof image === 'object' && 'url' in image) { + const content = ( +
+ {image.alt + {/* Hover Overlay */}
-
-