diff --git a/src/blocks/RenderBlocks.tsx b/src/blocks/RenderBlocks.tsx index 40b4222..1092345 100644 --- a/src/blocks/RenderBlocks.tsx +++ b/src/blocks/RenderBlocks.tsx @@ -8,6 +8,7 @@ import { ContentBlock } from '@/blocks/Content/Component' import { FormBlock } from '@/blocks/Form/Component' import { MediaBlock } from '@/blocks/MediaBlock/Component' import { SkillsBlock } from '@/blocks/Skills/Component' +import { SkillsMarqueeBlock } from '@/blocks/SkillsMarquee/Component' const blockComponents = { archive: ArchiveBlock, @@ -16,6 +17,7 @@ const blockComponents = { formBlock: FormBlock, mediaBlock: MediaBlock, skills: SkillsBlock, + skillsMarquee: SkillsMarqueeBlock, } export const RenderBlocks: React.FC<{ diff --git a/src/blocks/SkillsMarquee/SkillsMarquee-Component.tsx b/src/blocks/SkillsMarquee/SkillsMarquee-Component.tsx new file mode 100644 index 0000000..7c84756 --- /dev/null +++ b/src/blocks/SkillsMarquee/SkillsMarquee-Component.tsx @@ -0,0 +1,96 @@ +'use client' + +import React from 'react' +import { cn } from '@/utilities/ui' +import { InfiniteSlider } from '@/components/ui/infinite-slider' +import { useThemeMode } from '@/hooks/useThemeMode' + +const LOGOS = [ + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/aftereffects-plain.svg', alt: 'aftereffects' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/almalinux-original.svg', alt: 'almalinux' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/amazonwebservices-original-wordmark.svg', alt: 'amazonwebservices' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/android-plain-wordmark.svg', alt: 'android' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/angularjs-plain-wordmark.svg', alt: 'angularjs' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/apache-line-wordmark.svg', alt: 'apache' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/apple-original.svg', alt: 'apple' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/azure-original-wordmark.svg', alt: 'azure' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/blender-original.svg', alt: 'blender' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/bootstrap-plain-wordmark.svg', alt: 'bootstrap' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/cloudflare-original-wordmark.svg', alt: 'cloudflare' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/cpanel-original-wordmark.svg', alt: 'cpanel' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/docker-plain-wordmark.svg', alt: 'docker' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/drupal-plain-wordmark.svg', alt: 'drupal' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/eslint-plain-wordmark.svg', alt: 'eslint' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/expo-original-wordmark.svg', alt: 'expo' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/figma-original.svg', alt: 'figma' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/flutter-original.svg', alt: 'flutter' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/forgejo-original.svg', alt: 'forgejo' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/fusion-original.svg', alt: 'fusion' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/gimp-original.svg', alt: 'gimp' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/github-original-wordmark.svg', alt: 'github' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/gitlab-plain-wordmark.svg', alt: 'gitlab' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/googlecloud-original-wordmark.svg', alt: 'googlecloud' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/html5-original-wordmark.svg', alt: 'html5' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/illustrator-original.svg', alt: 'illustrator' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/inkscape-plain-wordmark.svg', alt: 'inkscape' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/javascript-original.svg', alt: 'javascript' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/jira-original-wordmark.svg', alt: 'jira' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/jquery-plain-wordmark.svg', alt: 'jquery' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/kalilinux-original-wordmark.svg', alt: 'kalilinux' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/linux-original.svg', alt: 'linux' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/magento-plain-wordmark.svg', alt: 'magento' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/mongodb-original-wordmark.svg', alt: 'mongodb' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/nextjs-original-wordmark.svg', alt: 'nextjs' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/nginx-original.svg', alt: 'nginx' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/nodejs-original-wordmark.svg', alt: 'nodejs' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/opencl-original.svg', alt: 'opencl' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/photoshop-original.svg', alt: 'photoshop' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/php-original.svg', alt: 'php' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/premierepro-original.svg', alt: 'premierepro' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/prometheus-plain-wordmark.svg', alt: 'prometheus' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/proxmox-original-wordmark.svg', alt: 'proxmox' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/python-original-wordmark.svg', alt: 'python' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/rails-plain-wordmark.svg', alt: 'rails' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/reactnative-original-wordmark.svg', alt: 'reactnative' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/reactnavigation-original.svg', alt: 'reactnavigation' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/slack-original-wordmark.svg', alt: 'slack' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/swift-original-wordmark.svg', alt: 'swift' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/typescript-original.svg', alt: 'typescript' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/web3js-original.svg', alt: 'web3js' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/wordpress-original.svg', alt: 'wordpress' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/xcode-original.svg', alt: 'xcode' }, + { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/zend-original-wordmark.svg', alt: 'zend' }, +] + +type SkillsMarqueeBlockProps = { + heading?: string +} + +export function SkillsMarqueeBlock({ heading }: SkillsMarqueeBlockProps) { + const { isDark } = useThemeMode() + const text = isDark ? 'text-white/40' : 'text-black/40' + const border = isDark ? 'border-white/10' : 'border-black/10' + + return ( +
+

+ {heading || 'Skills'} +

+
+ + {LOGOS.map((l) => ( + {l.alt} + ))} + +
+
+ ) +} diff --git a/src/blocks/SkillsMarquee/SkillsMarquee-config.ts b/src/blocks/SkillsMarquee/SkillsMarquee-config.ts new file mode 100644 index 0000000..8e082cf --- /dev/null +++ b/src/blocks/SkillsMarquee/SkillsMarquee-config.ts @@ -0,0 +1,16 @@ +import type { Block } from 'payload' + +export const SkillsMarqueeBlock: Block = { + slug: 'skillsMarquee', + labels: { + singular: 'Skills Marquee', + plural: 'Skills Marquees', + }, + fields: [ + { + name: 'heading', + type: 'text', + defaultValue: 'Skills', + }, + ], +} diff --git a/src/collections/Pages/index.ts b/src/collections/Pages/index.ts index 79f2aa9..9b1c0ab 100644 --- a/src/collections/Pages/index.ts +++ b/src/collections/Pages/index.ts @@ -8,6 +8,7 @@ import { Content } from '../../blocks/Content/config' import { FormBlock } from '../../blocks/Form/config' import { MediaBlock } from '../../blocks/MediaBlock/config' import { SkillsBlock } from '../../blocks/Skills/config' +import { SkillsMarqueeBlock } from '../../blocks/SkillsMarquee/config' import { hero } from '@/heros/config' import { slugField } from 'payload' import { populatePublishedAt } from '../../hooks/populatePublishedAt' @@ -30,9 +31,6 @@ export const Pages: CollectionConfig<'pages'> = { read: authenticatedOrPublished, update: authenticated, }, - // This config controls what's populated by default when a page is referenced - // https://payloadcms.com/docs/queries/select#defaultpopulate-collection-config-property - // Type safe if the collection slug generic is passed to `CollectionConfig` - `CollectionConfig<'pages'> defaultPopulate: { title: true, slug: true, @@ -73,7 +71,7 @@ export const Pages: CollectionConfig<'pages'> = { { name: 'layout', type: 'blocks', - blocks: [CallToAction, Content, MediaBlock, Archive, FormBlock, SkillsBlock], + blocks: [CallToAction, Content, MediaBlock, Archive, FormBlock, SkillsBlock, SkillsMarqueeBlock], required: true, admin: { initCollapsed: true, @@ -97,13 +95,9 @@ export const Pages: CollectionConfig<'pages'> = { MetaImageField({ relationTo: 'media', }), - MetaDescriptionField({}), PreviewField({ - // if the `generateUrl` function is configured hasGenerateFn: true, - - // field paths to match the target field for data titlePath: 'meta.title', descriptionPath: 'meta.description', }), @@ -128,10 +122,10 @@ export const Pages: CollectionConfig<'pages'> = { versions: { drafts: { autosave: { - interval: 100, // We set this interval for optimal live preview + interval: 100, }, schedulePublish: true, }, maxPerDoc: 50, }, -} +} \ No newline at end of file diff --git a/src/components/HeroPage.tsx b/src/components/HeroPage.tsx index 7d5017e..4c49e2b 100644 --- a/src/components/HeroPage.tsx +++ b/src/components/HeroPage.tsx @@ -1,17 +1,11 @@ 'use client' -import React, { useEffect, useRef, useState } from 'react' +import React, { useEffect, useRef } from 'react' import { cn } from '@/utilities/ui' -import { InfiniteSlider } from '@/components/ui/infinite-slider' -import { ArrowRightIcon, PhoneCallIcon } from 'lucide-react' -import { createPortal } from 'react-dom' -import { MenuToggleIcon } from '@/components/ui/menu-toggle-icon' -import { useScroll } from '@/components/ui/use-scroll' import { useThemeMode } from '@/hooks/useThemeMode' import { CMSLink } from '@/components/Link' import RichText from '@/components/RichText' import type { Page } from '@/payload-types' -import { Button } from '@/components/ui/button' // ─── Types ──────────────────────────────────────────────────────────────────── @@ -171,30 +165,23 @@ function Background({ isDark }: { isDark: boolean }) { type HeroProps = Pick function HeroSection({ isDark, richText, links }: HeroProps & { isDark: boolean }) { - const muted = isDark ? 'text-white/55' : 'text-black/55' const borderLine = isDark ? 'bg-white/10' : 'bg-black/10' const borderLineFaint = isDark ? 'bg-white/5' : 'bg-black/5' const richTextColor = isDark ? 'text-white' : 'text-black' return (
- {/* Vertical border lines */}
- ) -} - -// ─── Logo cloud ─────────────────────────────────────────────────────────────── - -const LOGOS = [ - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/aftereffects-plain.svg', alt: 'aftereffects' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/almalinux-original.svg', alt: 'almalinux' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/amazonwebservices-original-wordmark.svg', alt: 'amazonwebservices' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/android-plain-wordmark.svg', alt: 'android' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/angularjs-plain-wordmark.svg', alt: 'angularjs' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/apache-line-wordmark.svg', alt: 'apache' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/apple-original.svg', alt: 'apple' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/azure-original-wordmark.svg', alt: 'azure' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/blender-original.svg', alt: 'blender' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/bootstrap-plain-wordmark.svg', alt: 'bootstrap' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/cloudflare-original-wordmark.svg', alt: 'cloudflare' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/cpanel-original-wordmark.svg', alt: 'cpanel' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/docker-plain-wordmark.svg', alt: 'docker' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/drupal-plain-wordmark.svg', alt: 'drupal' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/eslint-plain-wordmark.svg', alt: 'eslint' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/expo-original-wordmark.svg', alt: 'expo' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/figma-original.svg', alt: 'figma' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/flutter-original.svg', alt: 'flutter' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/forgejo-original.svg', alt: 'forgejo' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/fusion-original.svg', alt: 'fusion' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/gimp-original.svg', alt: 'gimp' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/github-original-wordmark.svg', alt: 'github' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/gitlab-plain-wordmark.svg', alt: 'gitlab' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/googlecloud-original-wordmark.svg', alt: 'googlecloud' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/html5-original-wordmark.svg', alt: 'html5' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/illustrator-original.svg', alt: 'illustrator' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/inkscape-plain-wordmark.svg', alt: 'inkscape' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/javascript-original.svg', alt: 'javascript' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/jira-original-wordmark.svg', alt: 'jira' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/jquery-plain-wordmark.svg', alt: 'jquery' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/kalilinux-original-wordmark.svg', alt: 'kalilinux' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/linux-original.svg', alt: 'linux' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/magento-plain-wordmark.svg', alt: 'magento' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/mongodb-original-wordmark.svg', alt: 'mongodb' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/nextjs-original-wordmark.svg', alt: 'nextjs' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/nginx-original.svg', alt: 'nginx' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/nodejs-original-wordmark.svg', alt: 'nodejs' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/opencl-original.svg', alt: 'opencl' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/photoshop-original.svg', alt: 'photoshop' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/php-original.svg', alt: 'php' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/premierepro-original.svg', alt: 'premierepro' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/prometheus-plain-wordmark.svg', alt: 'prometheus' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/proxmox-original-wordmark.svg', alt: 'proxmox' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/python-original-wordmark.svg', alt: 'python' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/rails-plain-wordmark.svg', alt: 'rails' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/reactnative-original-wordmark.svg', alt: 'reactnative' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/reactnavigation-original.svg', alt: 'reactnavigation' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/slack-original-wordmark.svg', alt: 'slack' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/swift-original-wordmark.svg', alt: 'swift' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/typescript-original.svg', alt: 'typescript' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/web3js-original.svg', alt: 'web3js' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/wordpress-original.svg', alt: 'wordpress' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/xcode-original.svg', alt: 'xcode' }, - { src: 'https://portfolio-media.s3web.bymackie.com/Skill_logo/zend-original-wordmark.svg', alt: 'zend' }, -] - -function LogosSection({ isDark }: { isDark: boolean }) { - const text = isDark ? 'text-white/40' : 'text-black/40' - const border = isDark ? 'border-white/10' : 'border-black/10' - - return ( -
-

- Skills -

-
- - {LOGOS.map((l) => ( - {l.alt} - ))} -
) @@ -330,29 +227,23 @@ interface HeroPageProps { } export default function HeroPage({ richText, links, children }: HeroPageProps) { - const { isDark, toggle } = useThemeMode() + const { isDark } = useThemeMode() return (
- - {/* Canvas background — fixed behind everything */}
- - {/* Page content */}
- {children && ( -
+
{children}
)}
-
) }