first commit

This commit is contained in:
Yehoshua Sandler 2025-04-08 18:38:20 -05:00
parent badfbd59f7
commit 86d8d1b3f7
42 changed files with 2413 additions and 161 deletions

View File

@ -18,6 +18,10 @@ const nextConfig = {
protocol: url.protocol.replace(':', ''),
}
}),
{
protocol: 'https',
hostname: 'images.unsplash.com',
},
],
},
reactStrictMode: true,
@ -25,3 +29,4 @@ const nextConfig = {
}
export default withPayload(nextConfig, { devBundleServerPackages: false })

53
package-lock.json generated
View File

@ -9,6 +9,7 @@
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"@heroicons/react": "^2.2.0",
"@payloadcms/admin-bar": "3.31.0",
"@payloadcms/db-postgres": "3.31.0",
"@payloadcms/live-preview-react": "3.31.0",
@ -28,6 +29,7 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"cross-env": "^7.0.3",
"framer-motion": "^12.6.3",
"geist": "^1.3.0",
"graphql": "^16.8.2",
"lucide-react": "^0.378.0",
@ -2494,6 +2496,15 @@
"integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==",
"license": "MIT"
},
"node_modules/@heroicons/react": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.2.0.tgz",
"integrity": "sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==",
"license": "MIT",
"peerDependencies": {
"react": ">= 16 || ^19.0.0-rc"
}
},
"node_modules/@humanfs/core": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
@ -8521,6 +8532,33 @@
"url": "https://github.com/sponsors/rawify"
}
},
"node_modules/framer-motion": {
"version": "12.6.3",
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.6.3.tgz",
"integrity": "sha512-2hsqknz23aloK85bzMc9nSR2/JP+fValQ459ZTVElFQ0xgwR2YqNjYSuDZdFBPOwVCt4Q9jgyTt6hg6sVOALzw==",
"license": "MIT",
"dependencies": {
"motion-dom": "^12.6.3",
"motion-utils": "^12.6.3",
"tslib": "^2.4.0"
},
"peerDependencies": {
"@emotion/is-prop-valid": "*",
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@emotion/is-prop-valid": {
"optional": true
},
"react": {
"optional": true
},
"react-dom": {
"optional": true
}
}
},
"node_modules/fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
@ -10612,6 +10650,21 @@
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
"license": "MIT"
},
"node_modules/motion-dom": {
"version": "12.6.3",
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.6.3.tgz",
"integrity": "sha512-gRY08RjcnzgFYLemUZ1lo/e9RkBxR+6d4BRvoeZDSeArG4XQXERSPapKl3LNQRu22Sndjf1h+iavgY0O4NrYqA==",
"license": "MIT",
"dependencies": {
"motion-utils": "^12.6.3"
}
},
"node_modules/motion-utils": {
"version": "12.6.3",
"resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.6.3.tgz",
"integrity": "sha512-R/b3Ia2VxtTNZ4LTEO5pKYau1OUNHOuUfxuP0WFCTDYdHkeTBR9UtxR1cc8mDmKr8PEhmmfnTKGz3rSMjNRoRg==",
"license": "MIT"
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",

View File

@ -19,7 +19,9 @@
"start": "cross-env NODE_OPTIONS=--no-deprecation next start"
},
"dependencies": {
"@heroicons/react": "^2.2.0",
"@payloadcms/admin-bar": "3.31.0",
"@payloadcms/db-postgres": "3.31.0",
"@payloadcms/live-preview-react": "3.31.0",
"@payloadcms/next": "3.31.0",
"@payloadcms/payload-cloud": "3.31.0",
@ -37,6 +39,7 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"cross-env": "^7.0.3",
"framer-motion": "^12.6.3",
"geist": "^1.3.0",
"graphql": "^16.8.2",
"lucide-react": "^0.378.0",
@ -49,8 +52,7 @@
"react-hook-form": "7.45.4",
"sharp": "0.32.6",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7",
"@payloadcms/db-postgres": "3.31.0"
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"@eslint/eslintrc": "^3.2.0",

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
aria-label="Docker" role="img"
viewBox="0 0 512 512"><rect
width="512" height="512"
rx="15%"
fill="#ffffff"/><path stroke="#066da5" stroke-width="38" d="M296 226h42m-92 0h42m-91 0h42m-91 0h41m-91 0h42m8-46h41m8 0h42m7 0h42m-42-46h42"/><path fill="#066da5" d="m472 228s-18-17-55-11c-4-29-35-46-35-46s-29 35-8 74c-6 3-16 7-31 7H68c-5 19-5 145 133 145 99 0 173-46 208-130 52 4 63-39 63-39"/></svg>

After

Width:  |  Height:  |  Size: 474 B

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<svg width="800px" height="800px" viewBox="-4 -4 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.58536 17.4132C1.80488 16.6327 1.80488 15.3673 2.58536 14.5868L14.5868 2.58536C15.3673 1.80488 16.6327 1.80488 17.4132 2.58536L29.4146 14.5868C30.1951 15.3673 30.1951 16.6327 29.4146 17.4132L17.4132 29.4146C16.6327 30.1951 15.3673 30.1951 14.5868 29.4146L2.58536 17.4132Z" fill="#EE513B"/>
<path d="M12.1489 5.06152L10.9336 6.27686L14.0725 9.41577C13.9455 9.68819 13.8746 9.99201 13.8746 10.3124C13.8746 11.222 14.4461 11.9981 15.2496 12.3012V19.9798C14.4461 20.2829 13.8746 21.059 13.8746 21.9686C13.8746 23.1422 14.826 24.0936 15.9996 24.0936C17.1732 24.0936 18.1246 23.1422 18.1246 21.9686C18.1246 21.144 17.6549 20.429 16.9684 20.0768V12.3117L19.9689 15.3122C19.8481 15.5791 19.7809 15.8754 19.7809 16.1874C19.7809 17.361 20.7323 18.3124 21.9059 18.3124C23.0795 18.3124 24.0309 17.361 24.0309 16.1874C24.0309 15.0138 23.0795 14.0624 21.9059 14.0624C21.6778 14.0624 21.4582 14.0983 21.2522 14.1648L18.0297 10.9423C18.0914 10.7433 18.1246 10.5317 18.1246 10.3124C18.1246 9.13878 17.1732 8.18738 15.9996 8.18738C15.7803 8.18738 15.5688 8.22061 15.3697 8.2823L12.1489 5.06152Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

8
public/icons/go-icon.svg Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="800px" height="800px" viewBox="0 -160 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
<g>
<path d="M292.533152,13.2950639 L293.657233,14.0455076 C306.869315,22.7704678 316.342129,34.7361275 322.574244,49.1946331 C324.069951,51.4381943 323.072813,52.6846171 320.081398,53.4324709 L315.017741,54.7277932 C303.571167,57.6768058 294.487155,60.1566573 283.191384,63.10567 L276.74841,64.7843862 C274.428264,65.3583626 273.787695,65.1170696 271.320433,62.3073717 L270.972336,61.9081465 C267.453024,57.9195933 264.816991,55.2559574 260.154613,52.878088 L259.255961,52.4353326 C243.551033,44.7075107 228.344673,46.9510719 214.135452,56.1746012 C197.184101,67.1431227 188.459141,83.3466202 188.708425,103.538671 C188.95771,123.481438 202.668362,139.93422 222.361843,142.67635 C239.313195,144.919911 253.522416,138.937081 264.740222,126.223568 C266.983783,123.481438 268.978059,120.490023 271.470905,117.000039 L223.358982,117.000039 C218.124006,117.000039 216.877583,113.759339 218.622575,109.521501 L219.486848,107.487264 C222.690544,100.033179 227.659682,89.3185944 230.887235,83.1925665 L231.591356,81.8743455 C232.452883,80.3801337 234.202861,78.3609287 237.568203,78.3609287 L317.791861,78.3603482 C321.394911,66.9456209 327.24084,56.159659 335.038473,45.9539335 C353.236247,22.0226141 375.17329,9.55838523 404.838154,4.32340907 C430.265181,-0.163713323 454.196501,2.32913245 475.884259,17.0369225 C495.577741,30.4982897 507.792685,48.6960639 511.033385,72.6273834 C515.271222,106.280802 505.549124,133.702105 482.365658,157.134856 C465.912876,173.836922 445.720825,184.306875 422.537359,189.043282 C415.806676,190.289704 409.075992,190.538989 402.594593,191.286843 C379.909697,190.788274 359.219077,184.306875 341.769156,169.3498 C329.496056,158.740849 321.041799,145.701725 316.840932,130.522127 C313.926247,136.409796 310.44016,142.04853 306.370746,147.412757 C288.422257,171.094792 264.989506,185.802582 235.324641,189.791135 C210.894753,193.031835 188.209856,188.295428 168.26709,173.338353 C149.820031,159.378417 139.350079,140.931358 136.607949,117.997177 C133.367249,90.8251575 141.344356,66.3952689 157.797138,44.9567952 C175.496343,21.7733295 198.929093,7.06553943 227.59682,1.8305633 C250.59563,-2.32879605 272.633891,0.235689133 292.533152,13.2950639 L292.533152,13.2950639 Z M411.120284,49.0171223 L410.322415,49.1946331 C387.138949,54.4296092 372.181875,69.1373993 366.697614,92.5701496 C362.210492,112.014347 371.683306,131.707829 389.631795,139.684935 C403.342447,145.667765 417.053099,144.919911 430.265181,138.189228 C449.958663,127.96856 460.6779,112.014347 461.924323,90.575873 C461.675038,87.3351735 461.675038,84.8423277 461.176469,82.3494819 C456.739764,57.9476028 434.511926,44.025432 411.120284,49.0171223 L411.120284,49.0171223 Z M116.415898,94.5644262 C117.413036,94.5644262 117.911605,95.3122799 117.911605,96.3094183 L117.413036,102.292248 C117.413036,103.289387 116.415898,104.03724 115.668044,104.03724 L61.3240061,103.787956 C60.3268678,103.787956 60.0775833,103.040102 60.5761524,102.292248 L64.0661365,96.0601337 C64.5647057,95.3122799 65.561844,94.5644262 66.5589823,94.5644262 L116.415898,94.5644262 Z M121.900159,71.6302451 C122.897297,71.6302451 123.395866,72.3780988 123.146581,73.1259525 L121.152305,79.1087824 C120.90302,80.1059207 119.905882,80.6044899 118.908744,80.6044899 L0.99713831,80.8537744 C0,80.8537744 -0.249284578,80.3552053 0.249284578,79.6073515 L5.48426071,72.8766679 C5.98282987,72.1288142 7.22925276,71.6302451 8.22639107,71.6302451 L121.900159,71.6302451 Z M134.862957,48.6960639 C135.860095,48.6960639 136.109379,49.4439176 135.61081,50.1917714 L131.372973,56.6731704 C130.874403,57.4210241 129.62798,58.1688779 128.880127,58.1688779 L38.6391096,57.9195933 C37.6419713,57.9195933 37.3926867,57.4210241 37.8912558,56.6731704 L43.126232,49.9424868 C43.6248011,49.1946331 44.871224,48.6960639 45.8683623,48.6960639 L134.862957,48.6960639 Z" fill="#00ACD7" fill-rule="nonzero">
</path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="800px" height="800px" viewBox="-48 -48 356 356" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
<g>
<path d="M119.616813,0.0688905149 C119.066276,0.118932037 117.314565,0.294077364 115.738025,0.419181169 C79.3775171,3.69690087 45.3192571,23.3131775 23.7481916,53.4631946 C11.7364614,70.2271045 4.05395894,89.2428829 1.15112414,109.384595 C0.12512219,116.415429 0,118.492153 0,128.025062 C0,137.557972 0.12512219,139.634696 1.15112414,146.665529 C8.10791789,194.730411 42.3163245,235.11392 88.7116325,250.076335 C97.0197458,252.753556 105.778299,254.580072 115.738025,255.680985 C119.616813,256.106338 136.383187,256.106338 140.261975,255.680985 C157.453763,253.779407 172.017986,249.525878 186.382014,242.194795 C188.584164,241.068861 189.00958,240.768612 188.709286,240.518404 C188.509091,240.36828 179.124927,227.782837 167.86393,212.570214 L147.393939,184.922273 L121.743891,146.965779 C107.630108,126.098464 96.0187683,109.034305 95.9186706,109.034305 C95.8185728,109.009284 95.7184751,125.873277 95.6684262,146.465363 C95.5933529,182.52028 95.5683284,183.971484 95.1178886,184.82219 C94.4672532,186.048207 93.9667644,186.548623 92.915738,187.099079 C92.114956,187.499411 91.4142717,187.574474 87.6355816,187.574474 L83.3063539,187.574474 L82.1552297,186.848872 C81.4044966,186.373477 80.8539589,185.747958 80.4785924,185.022356 L79.9530792,183.896422 L80.0031281,133.729796 L80.0782014,83.5381493 L80.8539589,82.5623397 C81.25435,82.0369037 82.1051808,81.3613431 82.7057674,81.0360732 C83.7317693,80.535658 84.1321603,80.4856165 88.4613881,80.4856165 C93.5663734,80.4856165 94.4172043,80.6857826 95.7434995,82.1369867 C96.1188661,82.5373189 110.007429,103.454675 126.623656,128.650581 C143.239883,153.846488 165.962072,188.250034 177.122972,205.139048 L197.392766,235.839522 L198.418768,235.163961 C207.502639,229.259062 217.112023,220.852086 224.719453,212.09482 C240.910264,193.504394 251.345455,170.835585 254.848876,146.665529 C255.874878,139.634696 256,137.557972 256,128.025062 C256,118.492153 255.874878,116.415429 254.848876,109.384595 C247.892082,61.3197135 213.683675,20.9362052 167.288368,5.97379012 C159.105376,3.32158945 150.396872,1.49507389 140.637341,0.394160408 C138.234995,0.143952798 121.693842,-0.131275573 119.616813,0.0688905149 L119.616813,0.0688905149 Z M172.017986,77.4831252 C173.219159,78.0836234 174.195112,79.2345784 174.545455,80.435575 C174.74565,81.0861148 174.795699,94.9976579 174.74565,126.348671 L174.670577,171.336 L166.73783,159.17591 L158.780059,147.01582 L158.780059,114.313685 C158.780059,93.1711423 158.880156,81.2862808 159.030303,80.7108033 C159.430694,79.3096407 160.306549,78.2087272 161.507722,77.5581875 C162.533724,77.0327515 162.909091,76.98271 166.837928,76.98271 C170.541544,76.98271 171.19218,77.0327515 172.017986,77.4831252 Z" fill="#000000">
</path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
public/images/map.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -8,6 +8,7 @@ import type { Header } from '@/payload-types'
import { Logo } from '@/components/Logo/Logo'
import { HeaderNav } from './Nav'
import { ChevronRightIcon } from 'lucide-react'
interface HeaderClientProps {
data: Header
@ -32,9 +33,22 @@ export const HeaderClient: React.FC<HeaderClientProps> = ({ data }) => {
return (
<header className="container relative z-20 " {...(theme ? { 'data-theme': theme } : {})}>
<div className="py-8 flex justify-between">
<Link href="/">
<div className="flex align-middle items-center">
<Link href="/" className="block">
<Logo loading="eager" priority="high" className="invert dark:invert-0" />
</Link>
<div className=" ml-3">
<h1 className="text-black text-lg font-medium">Beitzah Technology Solutions</h1>
<Link
href="/faq"
className="flex items-center gap-1 rounded-full bg-fuchsia-950/35 px-3 py-0.5 text-sm/6 font-medium text-white data-hover:bg-fuchsia-950/30"
>
See our FAQ to learn more about our process.
<ChevronRightIcon className="size-4" />
</Link>
</div>
</div>
<HeaderNav data={data} />
</div>
</header>

View File

@ -5,7 +5,6 @@ import configPromise from '@payload-config'
import { getPayload, type RequiredDataFromCollectionSlug } from 'payload'
import { draftMode } from 'next/headers'
import React, { cache } from 'react'
import { homeStatic } from '@/endpoints/seed/home-static'
import { RenderBlocks } from '@/blocks/RenderBlocks'
import { RenderHero } from '@/heros/RenderHero'
@ -48,16 +47,9 @@ export default async function Page({ params: paramsPromise }: Args) {
const { slug = 'home' } = await paramsPromise
const url = '/' + slug
let page: RequiredDataFromCollectionSlug<'pages'> | null
page = await queryPageBySlug({
const page: RequiredDataFromCollectionSlug<'pages'> | null = await queryPageBySlug({
slug,
})
// Remove this code once your website is seeded
if (!page && slug === 'home') {
page = homeStatic
}
}) || null
if (!page) {
return <PayloadRedirects url={url} />

View File

@ -50,7 +50,7 @@
}
[data-theme='dark'] {
--background: 0 0% 0%;
--background: 215 28% 10%;
--foreground: 210 40% 98%;
--card: 0 0% 4%;

View File

@ -7,14 +7,26 @@ import { ParagraphFeatureClient as ParagraphFeatureClient_e70f5e05f09f93e00b997e
import { UnderlineFeatureClient as UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { BoldFeatureClient as BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { ItalicFeatureClient as ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { AlignFeatureClient as AlignFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { BlockquoteFeatureClient as BlockquoteFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { UnorderedListFeatureClient as UnorderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { LinkFeatureClient as LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { HorizontalRuleFeatureClient as HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { UploadFeatureClient as UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { RelationshipFeatureClient as RelationshipFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { ChecklistFeatureClient as ChecklistFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { OrderedListFeatureClient as OrderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { IndentFeatureClient as IndentFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { InlineCodeFeatureClient as InlineCodeFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { SuperscriptFeatureClient as SuperscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { SubscriptFeatureClient as SubscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { StrikethroughFeatureClient as StrikethroughFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { OverviewComponent as OverviewComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client'
import { MetaTitleComponent as MetaTitleComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client'
import { MetaImageComponent as MetaImageComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client'
import { MetaDescriptionComponent as MetaDescriptionComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client'
import { PreviewComponent as PreviewComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client'
import { SlugComponent as SlugComponent_92cc057d0a2abb4f6cf0307edf59f986 } from '@/fields/slug/SlugComponent'
import { HorizontalRuleFeatureClient as HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { BlocksFeatureClient as BlocksFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { LinkToDoc as LinkToDoc_aead06e4cbf6b2620c5c51c9ab283634 } from '@payloadcms/plugin-search/client'
import { ReindexButton as ReindexButton_aead06e4cbf6b2620c5c51c9ab283634 } from '@payloadcms/plugin-search/client'
@ -24,45 +36,40 @@ import { default as default_1a7510af427896d367a49dbf838d2de6 } from '@/component
import { default as default_8a7ab0eb7ab5c511aba12e68480bfe5e } from '@/components/BeforeLogin'
export const importMap = {
'@payloadcms/richtext-lexical/rsc#RscEntryLexicalCell':
RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e,
'@payloadcms/richtext-lexical/rsc#RscEntryLexicalField':
RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e,
'@payloadcms/richtext-lexical/client#InlineToolbarFeatureClient':
InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@payloadcms/richtext-lexical/client#FixedToolbarFeatureClient':
FixedToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@payloadcms/richtext-lexical/client#HeadingFeatureClient':
HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@payloadcms/richtext-lexical/client#ParagraphFeatureClient':
ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@payloadcms/richtext-lexical/client#UnderlineFeatureClient':
UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@payloadcms/richtext-lexical/client#BoldFeatureClient':
BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@payloadcms/richtext-lexical/client#ItalicFeatureClient':
ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@payloadcms/richtext-lexical/client#LinkFeatureClient':
LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@payloadcms/plugin-seo/client#OverviewComponent':
OverviewComponent_a8a977ebc872c5d5ea7ee689724c0860,
'@payloadcms/plugin-seo/client#MetaTitleComponent':
MetaTitleComponent_a8a977ebc872c5d5ea7ee689724c0860,
'@payloadcms/plugin-seo/client#MetaImageComponent':
MetaImageComponent_a8a977ebc872c5d5ea7ee689724c0860,
'@payloadcms/plugin-seo/client#MetaDescriptionComponent':
MetaDescriptionComponent_a8a977ebc872c5d5ea7ee689724c0860,
'@payloadcms/plugin-seo/client#PreviewComponent':
PreviewComponent_a8a977ebc872c5d5ea7ee689724c0860,
'@/fields/slug/SlugComponent#SlugComponent': SlugComponent_92cc057d0a2abb4f6cf0307edf59f986,
'@payloadcms/richtext-lexical/client#HorizontalRuleFeatureClient':
HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@payloadcms/richtext-lexical/client#BlocksFeatureClient':
BlocksFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@payloadcms/plugin-search/client#LinkToDoc': LinkToDoc_aead06e4cbf6b2620c5c51c9ab283634,
'@payloadcms/plugin-search/client#ReindexButton': ReindexButton_aead06e4cbf6b2620c5c51c9ab283634,
'@/Header/RowLabel#RowLabel': RowLabel_ec255a65fa6fa8d1faeb09cf35284224,
'@/Footer/RowLabel#RowLabel': RowLabel_1f6ff6ff633e3695d348f4f3c58f1466,
'@/components/BeforeDashboard#default': default_1a7510af427896d367a49dbf838d2de6,
'@/components/BeforeLogin#default': default_8a7ab0eb7ab5c511aba12e68480bfe5e,
"@payloadcms/richtext-lexical/rsc#RscEntryLexicalCell": RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e,
"@payloadcms/richtext-lexical/rsc#RscEntryLexicalField": RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e,
"@payloadcms/richtext-lexical/client#InlineToolbarFeatureClient": InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#FixedToolbarFeatureClient": FixedToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#HeadingFeatureClient": HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#ParagraphFeatureClient": ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#UnderlineFeatureClient": UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#BoldFeatureClient": BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#ItalicFeatureClient": ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#AlignFeatureClient": AlignFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#BlockquoteFeatureClient": BlockquoteFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#UnorderedListFeatureClient": UnorderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#LinkFeatureClient": LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#HorizontalRuleFeatureClient": HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#UploadFeatureClient": UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#RelationshipFeatureClient": RelationshipFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#ChecklistFeatureClient": ChecklistFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#OrderedListFeatureClient": OrderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#IndentFeatureClient": IndentFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#InlineCodeFeatureClient": InlineCodeFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#SuperscriptFeatureClient": SuperscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#SubscriptFeatureClient": SubscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#StrikethroughFeatureClient": StrikethroughFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/plugin-seo/client#OverviewComponent": OverviewComponent_a8a977ebc872c5d5ea7ee689724c0860,
"@payloadcms/plugin-seo/client#MetaTitleComponent": MetaTitleComponent_a8a977ebc872c5d5ea7ee689724c0860,
"@payloadcms/plugin-seo/client#MetaImageComponent": MetaImageComponent_a8a977ebc872c5d5ea7ee689724c0860,
"@payloadcms/plugin-seo/client#MetaDescriptionComponent": MetaDescriptionComponent_a8a977ebc872c5d5ea7ee689724c0860,
"@payloadcms/plugin-seo/client#PreviewComponent": PreviewComponent_a8a977ebc872c5d5ea7ee689724c0860,
"@/fields/slug/SlugComponent#SlugComponent": SlugComponent_92cc057d0a2abb4f6cf0307edf59f986,
"@payloadcms/richtext-lexical/client#BlocksFeatureClient": BlocksFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/plugin-search/client#LinkToDoc": LinkToDoc_aead06e4cbf6b2620c5c51c9ab283634,
"@payloadcms/plugin-search/client#ReindexButton": ReindexButton_aead06e4cbf6b2620c5c51c9ab283634,
"@/Header/RowLabel#RowLabel": RowLabel_ec255a65fa6fa8d1faeb09cf35284224,
"@/Footer/RowLabel#RowLabel": RowLabel_1f6ff6ff633e3695d348f4f3c58f1466,
"@/components/BeforeDashboard#default": default_1a7510af427896d367a49dbf838d2de6,
"@/components/BeforeLogin#default": default_8a7ab0eb7ab5c511aba12e68480bfe5e
}

View File

@ -0,0 +1,72 @@
import { Heading, Subheading } from '@/components/Headings/Headings'
import type { ArticleBlock as ArticleBlockProps } from '@/payload-types'
import { Container } from '@/components/Container/Container'
import RichText from '@/components/RichText'
import { cn } from '@/utilities/ui'
import { CMSLink } from '@/components/Link'
import Image from 'next/image'
import clsx from 'clsx'
const colsSpanClasses = {
full: '12',
half: '6',
oneThird: '4',
twoThirds: '8',
}
export const ArticleBlock: React.FC<ArticleBlockProps> = (props) => {
const { heading, subheading, brief, columns } = props
return (
<Container>
<Subheading>{subheading}</Subheading>
<Heading as="h3" className="mt-2 max-w-3xl">
{heading}
</Heading>
<div className="mt-6 text-xl/8 text-balance text-gray-700 dark:text-gray-50">
{brief && <RichText data={brief} enableGutter={false} />}
</div>
{columns &&
columns.length > 0 &&
columns.map((col) => {
const { enableLink, link, richText, size, imageUrls } = col
return (
<div className='overflow-hidden'>
{richText && imageUrls?.length && (
<div className="mt-20 grid grid-cols-1 lg:grid-cols-2 lg:gap-x-8 lg:gap-y-16">
<div className="lg:pr-8 text-justify">
<RichText data={richText} enableGutter={true} />
</div>
<div className="pt-16 lg:row-span-2 lg:-mr-16 xl:mr-auto">
<div className="-mx-8 grid grid-cols-2 gap-4 sm:-mx-16 sm:grid-cols-4 lg:mx-0 lg:grid-cols-2 lg:gap-4 xl:gap-8">
{imageUrls?.map((image, i) => (
<div className={clsx(
(i === 0 || i % 2 == 0)
? "aspect-square overflow-hidden rounded-xl shadow-xl outline-1 -outline-offset-1 outline-black/10"
: '-mt-8 aspect-square overflow-hidden rounded-xl shadow-xl outline-1 -outline-offset-1 outline-black/10 lg:-mt-28',
)}>
<Image
className="block size-full object-cover"
key={(image.url || '') + i}
width={image.width || 0}
height={image.height || 0}
src={image.url || ''}
alt={image.alt || ''}
/>
</div>
))}
</div>
</div>
</div>
)}
{enableLink && <CMSLink {...link} />}
</div>
)
})}
</Container>
)
}

View File

@ -0,0 +1,118 @@
import { FixedToolbarFeature, HeadingFeature, InlineToolbarFeature, lexicalEditor, UnorderedListFeature } from '@payloadcms/richtext-lexical'
import type { Block, Field } from 'payload'
import { link } from '@/fields/link'
const imageUrlFields: Field[] = [
{
name: 'url',
type: 'text',
},
{
name: 'alt',
type: 'text',
},
{
name: 'width',
type: 'number',
},
{
name: 'height',
type: 'number',
}
]
const columnFields: Field[] = [
{
name: 'size',
type: 'select',
defaultValue: 'oneThird',
options: [
{
label: 'One Third',
value: 'oneThird',
},
{
label: 'Half',
value: 'half',
},
{
label: 'Two Thirds',
value: 'twoThirds',
},
{
label: 'Full',
value: 'full',
},
],
},
{
name: 'richText',
type: 'richText',
editor: lexicalEditor({
features: ({ defaultFeatures }) => {
return [
...defaultFeatures,
FixedToolbarFeature(),
InlineToolbarFeature(),
]
},
}),
label: false,
},
{
name: 'enableLink',
type: 'checkbox',
},
link({
overrides: {
admin: {
condition: (_data, siblingData) => {
return Boolean(siblingData?.enableLink)
},
},
},
}),
{
name: 'imageUrls',
type: 'array',
fields: imageUrlFields,
}
]
export const ArticleBlock: Block = {
slug: 'article',
interfaceName: 'ArticleBlock',
fields: [
{
name: "heading",
type: "text"
},
{
name: "subheading",
type: "text"
},
{
name: 'brief',
type: 'richText',
editor: lexicalEditor({
features: ({ defaultFeatures }) => {
return [
...defaultFeatures,
FixedToolbarFeature(),
InlineToolbarFeature(),
]
},
}),
label: false,
},
{
name: 'columns',
type: 'array',
admin: {
initCollapsed: true,
},
fields: columnFields,
},
],
}

View File

@ -0,0 +1,31 @@
import { BentoCard } from '@/components/BentoCard/BentoCard'
import { Heading, Subheading } from '@/components/Headings/Headings'
import type { BentoBlock as BentoBlockProps } from '@/payload-types'
import { Container } from '@/components/Container/Container'
export const BentoBlock: React.FC<BentoBlockProps> = (props) => {
const { heading, subheading, graphics } = props
return (
<Container>
<Subheading>{subheading}</Subheading>
<Heading as="h3" className="mt-2 max-w-3xl">
{heading}
</Heading>
<div className="mt-10 grid grid-cols-1 gap-4 sm:mt-16 lg:grid-cols-6">
{graphics?.map((c) => (
<BentoCard
key={c.eyebrow}
eyebrow={c.eyebrow}
title={c.title}
description={c.description}
graphic={c.graphic || ''}
className={c.className || ''}
/>
)
)}
</div>
</Container>
)
}

View File

@ -0,0 +1,73 @@
import { Keyboard } from '@/components/Graphics/Keyboard'
import { LogoCluster } from '@/components/Graphics/LogoCluster'
import { Map as MapGraphic } from '@/components/Graphics/Map'
import type { Block, Field } from 'payload'
export const Graphics = new Map([
["animatedMapPins", MapGraphic],
["animatedLogoCluster", LogoCluster],
["animatedKeyboard", Keyboard],
])
const bentoSectionFields: Field[] = [
{
name: 'graphic',
type: 'select',
options: [
{
label: 'Animated Map with Pins',
value: 'animatedMapPins',
},
{
label: 'Animated Logo Cluster',
value: 'animatedLogoCluster',
},
{
label: 'Animated Keybaord',
value: 'animatedKeyboard',
},
],
},
{
name: 'eyebrow',
type: 'text',
},
{
name: 'title',
type: 'text',
},
{
name: 'description',
type: 'text',
},
{
name: 'className',
type: 'text',
},
]
export const BentoBlock: Block = {
slug: 'bento',
interfaceName: 'BentoBlock',
fields: [
{
name: "heading",
type: "text"
},
{
name: "subheading",
type: "text"
},
{
name: 'graphics',
type: 'array',
admin: {
initCollapsed: true,
},
fields: bentoSectionFields,
},
],
}

View File

@ -8,11 +8,11 @@ import { CMSLink } from '@/components/Link'
export const CallToActionBlock: React.FC<CTABlockProps> = ({ links, richText }) => {
return (
<div className="container">
<div className="bg-card rounded border-border border p-4 flex flex-col gap-8 md:flex-row md:justify-between md:items-center">
<div className="max-w-[48rem] flex items-center">
{richText && <RichText className="mb-0" data={richText} enableGutter={false} />}
<div className="bg-card border-border border rounded-xl p-16">
<div className="items-center">
{richText && <RichText className="mb-0" data={richText} enableGutter={true} />}
</div>
<div className="flex flex-col gap-8">
<div className="flex gap-8 justify-around max-w-32 mx-auto">
{(links || []).map(({ link }, i) => {
return <CMSLink key={i} size="lg" {...link} />
})}

View File

@ -5,9 +5,10 @@ import RichText from '@/components/RichText'
import type { ContentBlock as ContentBlockProps } from '@/payload-types'
import { CMSLink } from '../../components/Link'
import Image from 'next/image'
export const ContentBlock: React.FC<ContentBlockProps> = (props) => {
const { columns } = props
const { columns, isFullscreen, backgroundImage } = props
const colsSpanClasses = {
full: '12',
@ -16,9 +17,26 @@ export const ContentBlock: React.FC<ContentBlockProps> = (props) => {
twoThirds: '8',
}
console.log(isFullscreen, backgroundImage)
return (
<div className="container my-16">
<div className="grid grid-cols-4 lg:grid-cols-12 gap-y-8 gap-x-16">
<div className={cn(
"my-16",
isFullscreen ? "relative isolate overflow-hidden min-h-[100vh] flex align-middle items-center" : "container",
)}>
{!!backgroundImage && <Image
alt=""
src={backgroundImage}
className="absolute inset-0 -z-10 size-full object-cover"
width={2830}
height={1500}
/>
}
<div className={cn(
"grid grid-cols-4 lg:grid-cols-12 gap-y-8 gap-x-16",
!!backgroundImage && "container",
)}>
{columns &&
columns.length > 0 &&
columns.map((col, index) => {

View File

@ -40,7 +40,7 @@ const columnFields: Field[] = [
features: ({ rootFeatures }) => {
return [
...rootFeatures,
HeadingFeature({ enabledHeadingSizes: ['h2', 'h3', 'h4'] }),
HeadingFeature({ enabledHeadingSizes: ['h1', 'h2', 'h3', 'h4'] }),
FixedToolbarFeature(),
InlineToolbarFeature(),
]
@ -75,5 +75,13 @@ export const Content: Block = {
},
fields: columnFields,
},
{
name: 'backgroundImage',
type: 'text',
},
{
name: 'isFullscreen',
type: 'checkbox',
},
],
}

View File

@ -7,6 +7,8 @@ import { CallToActionBlock } from '@/blocks/CallToAction/Component'
import { ContentBlock } from '@/blocks/Content/Component'
import { FormBlock } from '@/blocks/Form/Component'
import { MediaBlock } from '@/blocks/MediaBlock/Component'
import { BentoBlock } from '@/blocks/Bento/Component'
import { ArticleBlock } from './ArticleBlock/Component'
const blockComponents = {
archive: ArchiveBlock,
@ -14,6 +16,8 @@ const blockComponents = {
cta: CallToActionBlock,
formBlock: FormBlock,
mediaBlock: MediaBlock,
bento: BentoBlock,
article: ArticleBlock,
}
export const RenderBlocks: React.FC<{

View File

@ -7,6 +7,7 @@ import { CallToAction } from '../../blocks/CallToAction/config'
import { Content } from '../../blocks/Content/config'
import { FormBlock } from '../../blocks/Form/config'
import { MediaBlock } from '../../blocks/MediaBlock/config'
import { BentoBlock } from '@/blocks/Bento/config'
import { hero } from '@/heros/config'
import { slugField } from '@/fields/slug'
import { populatePublishedAt } from '../../hooks/populatePublishedAt'
@ -20,6 +21,7 @@ import {
OverviewField,
PreviewField,
} from '@payloadcms/plugin-seo/fields'
import { ArticleBlock } from '@/blocks/ArticleBlock/config'
export const Pages: CollectionConfig<'pages'> = {
slug: 'pages',
@ -75,7 +77,7 @@ export const Pages: CollectionConfig<'pages'> = {
{
name: 'layout',
type: 'blocks',
blocks: [CallToAction, Content, MediaBlock, Archive, FormBlock],
blocks: [CallToAction, Content, MediaBlock, Archive, FormBlock, BentoBlock, ArticleBlock],
required: true,
admin: {
initCollapsed: true,

View File

@ -5,7 +5,7 @@ import { User } from 'src/payload-types'
// This means that we need to populate the authors manually here to protect user privacy
// GraphQL will not return mutated user data that differs from the underlying schema
// So we use an alternative `populatedAuthors` field to populate the user data, hidden from the admin UI
export const populateAuthors: CollectionAfterReadHook = async ({ doc, req, req: { payload } }) => {
export const populateAuthors: CollectionAfterReadHook = async ({ doc, req: { payload } }) => {
if (doc?.authors && doc?.authors?.length > 0) {
const authorDocs: User[] = []

View File

@ -0,0 +1,68 @@
'use client'
import { clsx } from 'clsx'
import { motion } from 'framer-motion'
import { Subheading } from '../Headings/Headings'
import { Graphics } from '@/blocks/Bento/config'
const getGraphicElementFromName = (graphicName?: string) => {
const graphicElement = Graphics.get(graphicName || '')
if (graphicElement) return graphicElement()
}
export function BentoCard({
dark = false,
className = '',
eyebrow,
title,
description,
graphic,
fade = [],
}: {
dark?: boolean
className?: string
eyebrow: React.ReactNode
title: React.ReactNode
description: React.ReactNode
graphic: string
fade?: ('top' | 'bottom')[]
}) {
return (
<motion.div
initial="idle"
whileHover="active"
variants={{ idle: {}, active: {} }}
data-dark={dark ? 'true' : undefined}
className={clsx(
className,
'group relative flex flex-col overflow-hidden rounded-lg',
'bg-white ring-1 shadow-xs ring-black/5',
'dark:bg-gray-800 dark:ring-white/15',
'lg:col-span-2',
)}
>
<div className="relative h-80 shrink-0">
{
getGraphicElementFromName(graphic)
}
{fade.includes('top') && (
<div className="absolute inset-0 bg-linear-to-b from-white to-50% dark:from-gray-800 dark:from-[-25%]" />
)}
{fade.includes('bottom') && (
<div className="absolute inset-0 bg-linear-to-t from-white to-50% dark:from-gray-800 dark:from-[-25%]" />
)}
</div>
<div className="relative p-10">
<Subheading as="h3" dark={dark}>
{eyebrow}
</Subheading>
<p className="mt-1 text-2xl/8 font-medium tracking-tight text-gray-950 dark:text-white">
{title}
</p>
<p className="mt-2 max-w-[600px] text-sm/6 text-gray-600 dark:text-gray-400">
{description}
</p>
</div>
</motion.div>
)
}

View File

@ -0,0 +1,15 @@
import { clsx } from 'clsx'
export function Container({
className,
children,
}: {
className?: string
children: React.ReactNode
}) {
return (
<div className={clsx(className, 'px-6 lg:px-8')}>
<div className="mx-auto max-w-2xl lg:max-w-7xl">{children}</div>
</div>
)
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,135 @@
'use client'
import { clsx } from 'clsx'
import { motion } from 'framer-motion'
import { MovingMark } from './Mark'
function Circle({ size, delay, opacity }: { size: number; delay: number; opacity: string }) {
return (
<motion.div
variants={{
idle: { width: `${size}px`, height: `${size}px` },
active: {
width: [`${size}px`, `${size + 10}px`, `${size}px`],
height: [`${size}px`, `${size + 10}px`, `${size}px`],
transition: {
duration: 0.75,
repeat: Infinity,
repeatDelay: 1.25,
ease: 'easeInOut',
delay,
},
},
}}
style={{ '--opacity': opacity } as React.CSSProperties}
className={clsx(
'absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full',
'bg-[radial-gradient(circle,transparent_25%,color-mix(in_srgb,var(--color-blue-500)_var(--opacity),transparent)_100%)]',
'ring-1 ring-blue-500/[8%] ring-inset',
)}
/>
)
}
function Circles() {
return (
<div className="absolute inset-0">
<Circle size={528} opacity="3%" delay={0.45} />
<Circle size={400} opacity="5%" delay={0.3} />
<Circle size={272} opacity="5%" delay={0.15} />
<Circle size={144} opacity="10%" delay={0} />
<div className="absolute inset-0 bg-linear-to-t from-white to-35%" />
</div>
)
}
function MainLogo() {
return (
<div className="absolute top-32 left-44 flex size-16 items-center justify-center rounded-full bg-white ring-1 shadow-sm ring-black/5">
<MovingMark className="h-9 fill-black" />
</div>
)
}
function Logo({
src,
left,
top,
hover,
}: {
src: string
left: number
top: number
hover: { x: number; y: number; rotate: number; delay: number }
}) {
return (
<motion.img
variants={{
idle: { x: 0, y: 0, rotate: 0 },
active: {
x: [0, hover.x, 0],
y: [0, hover.y, 0],
rotate: [0, hover.rotate, 0],
transition: {
duration: 0.75,
repeat: Infinity,
repeatDelay: 1.25,
ease: 'easeInOut',
delay: hover.delay,
},
},
}}
alt=""
src={src}
style={{ left, top } as React.CSSProperties}
className="absolute size-16 rounded-full bg-white ring-1 shadow-sm ring-black/5"
/>
)
}
export function LogoCluster() {
return (
<div aria-hidden="true" className="relative h-full overflow-hidden">
<Circles />
<div className="absolute left-1/2 h-full w-[26rem] -translate-x-1/2">
<MainLogo />
<Logo
src="/icons/docker-icon.svg"
left={360}
top={144}
hover={{ x: 6, y: 1, rotate: 5, delay: 0.38 }}
/>
<Logo
src="/icons/git-icon.svg"
left={285}
top={20}
hover={{ x: 4, y: -5, rotate: 6, delay: 0.3 }}
/>
<Logo
src="/icons/go-icon.svg"
left={255}
top={210}
hover={{ x: 3, y: 5, rotate: 7, delay: 0.2 }}
/>
<Logo
src="/icons/postgres-icon.svg"
left={144}
top={40}
hover={{ x: -2, y: -5, rotate: -6, delay: 0.15 }}
/>
<Logo
src="/icons/nextjs-icon.svg"
left={36}
top={56}
hover={{ x: -4, y: -5, rotate: -6, delay: 0.35 }}
/>
<Logo
src="/icons/linux-icon.svg"
left={96}
top={176}
hover={{ x: -3, y: 5, rotate: 3, delay: 0.15 }}
/>
</div>
</div>
)
}

View File

@ -0,0 +1,121 @@
'use client'
import {
ServerStackIcon,
CircleStackIcon,
UserGroupIcon,
MagnifyingGlassIcon,
BuildingStorefrontIcon,
} from '@heroicons/react/24/solid'
import { motion } from 'framer-motion'
import Image from 'next/image'
import { ForwardRefExoticComponent, RefAttributes, SVGProps } from 'react'
type HeroIcon = ForwardRefExoticComponent<
Omit<SVGProps<SVGSVGElement>, 'ref'> & {
title?: string | undefined
titleId?: string | undefined
} & RefAttributes<SVGSVGElement>
>
type IconProps = {
icon: HeroIcon
className?: string
}
function IconWrapper({ icon: Icon, className }: IconProps) {
return <Icon className={className} />
}
function Marker({
src,
icon,
iconClassNames,
top,
offset,
delay,
}: {
src?: string
icon?: HeroIcon
iconClassNames?: string
top: number
offset: number
delay: number
}) {
return (
<motion.div
variants={{
idle: { scale: 0, opacity: 0, rotateX: 0, rotate: 0, y: 0 },
active: { y: [-20, 0, 4, 0], scale: [0.75, 1], opacity: [0, 1] },
}}
transition={{ duration: 0.25, delay, ease: 'easeOut' }}
style={{ '--offset': `${offset}px`, top } as React.CSSProperties}
className="absolute left-[calc(50%+var(--offset))] size-[38px] drop-shadow-[0_3px_1px_rgba(0,0,0,.15)]"
>
<svg fill="none" viewBox="0 0 38 38" className="absolute size-full">
<path
d="M29.607 5.193c5.858 5.857 5.858 15.355 0 21.213l-9.9 9.9-.707.706-.708-.708-9.899-9.898c-5.857-5.858-5.857-15.356 0-21.213 5.858-5.858 15.356-5.858 21.214 0Z"
className="fill-black/5"
/>
<path
d="m28.9 25.698-9.9 9.9-9.9-9.9C3.634 20.232 3.634 11.367 9.1 5.9 14.569.432 23.433.432 28.9 5.9c5.467 5.468 5.467 14.332 0 19.8Z"
className="fill-white"
/>
</svg>
{src && !icon && (
<Image alt="" src={src} className="absolute top-[4px] left-[7px] size-6 rounded-full" />
)}
{!src && icon && (
<IconWrapper
icon={icon}
className={`absolute top-[4px] left-[7px] size-6 rounded-full ${iconClassNames}`}
/>
)}
</motion.div>
)
}
export function Map() {
return (
<div aria-hidden="true" className="relative size-full">
<div className="absolute inset-0 bg-[url(/images/map.png)] bg-[length:530px_430px] bg-[center_-75px] bg-no-repeat [mask-image:linear-gradient(to_bottom,black_50%,transparent)]" />
<div className="absolute inset-0">
<Marker
icon={ServerStackIcon}
top={96}
offset={-128}
delay={0.15}
iconClassNames="text-green-600"
/>
<Marker
icon={CircleStackIcon}
top={160}
offset={-16}
delay={0.4}
iconClassNames="text-orange-600"
/>
<Marker
icon={UserGroupIcon}
top={144}
offset={96}
delay={0.3}
iconClassNames="text-purple-600"
/>
<Marker
icon={MagnifyingGlassIcon}
top={192}
offset={64}
delay={0.6}
iconClassNames="text-yellow-700"
/>
<Marker
icon={BuildingStorefrontIcon}
top={224}
offset={-32}
delay={0.8}
iconClassNames="text-blue-600"
/>
</div>
</div>
)
}

View File

@ -0,0 +1,111 @@
'use client'
import { clsx } from 'clsx'
import { motion } from 'framer-motion'
export function MovingMark({ className }: { className?: string }) {
const transition = {
duration: 0.5,
ease: 'easeInOut',
}
return (
<motion.svg
variants={{ idle: {}, active: {} }}
initial="idle"
whileHover="active"
width={34}
height={34}
viewBox="0 0 34 34"
className={clsx(className, 'overflow-visible')}
>
<motion.g
variants={{
idle: { scale: 1, opacity: 1 },
active: {
scale: [1, 1.15, 1],
opacity: [1, 0.75, 1],
transition: {
...transition,
delay: 0,
},
},
}}
>
<motion.path d="M19.5986 18.5005C18.7702 19.9354 16.9354 20.427 15.5005 19.5986C14.0656 18.7701 13.574 16.9354 14.4024 15.5005C15.2309 14.0656 17.0656 13.574 18.5005 14.4024C19.9354 15.2308 20.427 17.0656 19.5986 18.5005Z" />
</motion.g>
<motion.g
variants={{
idle: { scale: 1, opacity: 1 },
active: {
scale: [1, 1.1, 1],
opacity: [1, 0.75, 1],
transition: {
...transition,
delay: 0.15,
},
},
}}
>
<path d="M23.2324 10.2074C22.6801 11.1639 21.4569 11.4917 20.5003 10.9394C19.5437 10.3871 19.216 9.16395 19.7683 8.20736C20.3205 7.25078 21.5437 6.92303 22.5003 7.47531C23.4569 8.0276 23.7846 9.25078 23.2324 10.2074Z" />
<path d="M19.7683 25.7933C19.216 24.8367 19.5437 23.6135 20.5003 23.0612C21.4569 22.5089 22.6801 22.8367 23.2324 23.7933C23.7847 24.7498 23.4569 25.973 22.5003 26.5253C21.5437 27.0776 20.3206 26.7498 19.7683 25.7933Z" />
<path d="M26 19C24.8954 19 24 18.1046 24 17C24 15.8955 24.8954 15 26 15C27.1046 15 28 15.8955 28 17C28 18.1046 27.1046 19 26 19Z" />
<path d="M14.2324 25.7933C13.6801 26.7499 12.4569 27.0777 11.5003 26.5254C10.5437 25.9731 10.216 24.7499 10.7683 23.7933C11.3205 22.8367 12.5437 22.509 13.5003 23.0613C14.4569 23.6136 14.7846 24.8367 14.2324 25.7933Z" />
<path d="M10.7682 10.2073C10.216 9.25078 10.5437 8.0276 11.5003 7.47532C12.4569 6.92303 13.6801 7.25078 14.2323 8.20737C14.7846 9.16395 14.4569 10.3871 13.5003 10.9394C12.5437 11.4917 11.3205 11.1639 10.7682 10.2073Z" />
<path d="M8 19C6.89543 19 6 18.1045 6 17C6 15.8954 6.89543 15 8 15C9.10457 15 10 15.8954 10 17C10 18.1045 9.10457 19 8 19Z" />
</motion.g>
<motion.g
variants={{
idle: { scale: 1, opacity: 1 },
active: {
scale: [1, 1.1, 1],
opacity: [1, 0.75, 1],
transition: {
...transition,
delay: 0.3,
},
},
}}
>
<path d="M25.8662 3.6447C25.5901 4.12299 24.9785 4.28686 24.5002 4.01072C24.0219 3.73458 23.858 3.12299 24.1342 2.6447C24.4103 2.1664 25.0219 2.00253 25.5002 2.27867C25.9785 2.55481 26.1424 3.1664 25.8662 3.6447Z" />
<path d="M33 18C32.4477 18 32 17.5522 32 17C32 16.4477 32.4477 16 33 16C33.5522 16 34 16.4477 34 17C34 17.5522 33.5522 18 33 18Z" />
<path d="M31.3556 9.86619C30.8773 10.1424 30.2658 9.97846 29.9896 9.50017C29.7135 9.02187 29.8773 8.41028 30.3556 8.13414C30.8339 7.858 31.4455 8.02187 31.7217 8.50017C31.9978 8.97846 31.8339 9.59005 31.3556 9.86619Z" />
<path d="M30.3556 25.8662C29.8773 25.5901 29.7134 24.9785 29.9896 24.5002C30.2657 24.0219 30.8773 23.858 31.3556 24.1342C31.8339 24.4103 31.9978 25.0219 31.7216 25.5002C31.4455 25.9785 30.8339 26.1424 30.3556 25.8662Z" />
<path d="M16 33C16 32.4477 16.4477 32 17 32C17.5523 32 18 32.4477 18 33C18 33.5523 17.5523 34 17 34C16.4477 34 16 33.5523 16 33Z" />
<path d="M24.1341 31.3557C23.858 30.8774 24.0219 30.2658 24.5002 29.9896C24.9785 29.7135 25.5901 29.8774 25.8662 30.3557C26.1423 30.834 25.9785 31.4455 25.5002 31.7217C25.0219 31.9978 24.4103 31.834 24.1341 31.3557Z" />
<path d="M9.8662 31.3556C9.59005 31.8339 8.97846 31.9978 8.50017 31.7216C8.02188 31.4455 7.858 30.8339 8.13415 30.3556C8.41029 29.8773 9.02188 29.7134 9.50017 29.9896C9.97846 30.2657 10.1424 30.8773 9.8662 31.3556Z" />
<path d="M1 18C0.447715 18 -3.44684e-08 17.5523 0 17C3.44684e-08 16.4477 0.447715 16 1 16C1.55228 16 2 16.4477 2 17C2 17.5523 1.55228 18 1 18Z" />
<path d="M3.6447 25.8662C3.1664 26.1424 2.55481 25.9785 2.27867 25.5002C2.00253 25.0219 2.1664 24.4103 2.6447 24.1342C3.12299 23.858 3.73458 24.0219 4.01072 24.5002C4.28686 24.9785 4.12299 25.5901 3.6447 25.8662Z" />
<path d="M2.6447 9.8662C2.1664 9.59005 2.00253 8.97846 2.27867 8.50017C2.55481 8.02188 3.1664 7.858 3.6447 8.13415C4.12299 8.41029 4.28686 9.02188 4.01072 9.50017C3.73458 9.97846 3.12299 10.1424 2.6447 9.8662Z" />
<path d="M16 1C16 0.447715 16.4477 -4.87226e-08 17 0C17.5523 4.87226e-08 18 0.447715 18 1C18 1.55228 17.5523 2 17 2C16.4477 2 16 1.55228 16 1Z" />
<path d="M8.13415 3.6447C7.858 3.16641 8.02188 2.55482 8.50017 2.27867C8.97846 2.00253 9.59005 2.16641 9.8662 2.6447C10.1424 3.12299 9.97846 3.73458 9.50017 4.01072C9.02188 4.28687 8.41029 4.12299 8.13415 3.6447Z" />
</motion.g>
</motion.svg>
)
}
export function Mark({ className }: { className?: string }) {
return (
<svg viewBox="0 0 34 34" fill="none" className={className}>
<path d="M19.598 18.5C18.7696 19.9349 16.9348 20.4265 15.4999 19.5981C14.065 18.7696 13.5734 16.9349 14.4018 15.5C15.2303 14.0651 17.065 13.5735 18.4999 14.4019C19.9348 15.2303 20.4264 17.0651 19.598 18.5Z" />
<path d="M23.232 10.2058C22.6797 11.1623 21.4565 11.4901 20.4999 10.9378C19.5433 10.3855 19.2156 9.16235 19.7679 8.20576C20.3201 7.24918 21.5433 6.92143 22.4999 7.47371C23.4565 8.026 23.7842 9.24918 23.232 10.2058Z" />
<path d="M19.7679 25.7944C19.2156 24.8378 19.5433 23.6146 20.4999 23.0623C21.4565 22.51 22.6797 22.8378 23.232 23.7944C23.7843 24.7509 23.4565 25.9741 22.4999 26.5264C21.5433 27.0787 20.3202 26.7509 19.7679 25.7944Z" />
<path d="M25.9999 19.0001C24.8953 19.0001 23.9999 18.1047 23.9999 17.0001C23.9999 15.8956 24.8953 15.0001 25.9999 15.0001C27.1045 15.0001 27.9999 15.8956 27.9999 17.0001C27.9999 18.1047 27.1045 19.0001 25.9999 19.0001Z" />
<path d="M14.232 25.7942C13.6797 26.7508 12.4565 27.0786 11.4999 26.5263C10.5433 25.974 10.2156 24.7508 10.7679 23.7942C11.3201 22.8376 12.5433 22.5099 13.4999 23.0622C14.4565 23.6145 14.7842 24.8376 14.232 25.7942Z" />
<path d="M10.7679 10.2059C10.2157 9.24936 10.5434 8.02618 11.5 7.4739C12.4566 6.92161 13.6798 7.24936 14.232 8.20595C14.7843 9.16253 14.4566 10.3857 13.5 10.938C12.5434 11.4903 11.3202 11.1625 10.7679 10.2059Z" />
<path d="M7.99999 19.0002C6.89542 19.0002 5.99999 18.1047 5.99999 17.0002C5.99999 15.8956 6.89542 15.0002 7.99999 15.0002C9.10456 15.0002 9.99999 15.8956 9.99999 17.0002C9.99999 18.1047 9.10456 19.0002 7.99999 19.0002Z" />
<path d="M25.8659 3.64359C25.5898 4.12188 24.9782 4.28575 24.4999 4.00961C24.0216 3.73347 23.8577 3.12188 24.1339 2.64359C24.41 2.16529 25.0216 2.00142 25.4999 2.27756C25.9782 2.5537 26.1421 3.16529 25.8659 3.64359Z" />
<path d="M33.0001 18.0002C32.4478 18.0002 32.0001 17.5524 32.0001 17.0002C32.0001 16.4479 32.4478 16.0002 33.0001 16.0002C33.5523 16.0002 34.0001 16.4479 34.0001 17.0002C34.0001 17.5524 33.5523 18.0002 33.0001 18.0002Z" />
<path d="M31.3561 9.86594C30.8778 10.1421 30.2663 9.97821 29.9901 9.49992C29.714 9.02162 29.8778 8.41003 30.3561 8.13389C30.8344 7.85775 31.446 8.02162 31.7222 8.49992C31.9983 8.97821 31.8344 9.5898 31.3561 9.86594Z" />
<path d="M30.3563 25.866C29.878 25.5899 29.7141 24.9783 29.9903 24.5C30.2664 24.0217 30.878 23.8578 31.3563 24.134C31.8346 24.4101 31.9985 25.0217 31.7223 25.5C31.4462 25.9783 30.8346 26.1422 30.3563 25.866Z" />
<path d="M16.0001 33.0001C16.0001 32.4478 16.4478 32.0001 17.0001 32.0001C17.5524 32.0001 18.0001 32.4478 18.0001 33.0001C18.0001 33.5524 17.5524 34.0001 17.0001 34.0001C16.4478 34.0001 16.0001 33.5524 16.0001 33.0001Z" />
<path d="M24.134 31.3566C23.8579 30.8783 24.0218 30.2667 24.5001 29.9905C24.9784 29.7144 25.59 29.8783 25.8661 30.3566C26.1422 30.8349 25.9784 31.4464 25.5001 31.7226C25.0218 31.9987 24.4102 31.8349 24.134 31.3566Z" />
<path d="M9.86593 31.3564C9.58978 31.8347 8.97819 31.9986 8.4999 31.7224C8.02161 31.4463 7.85773 30.8347 8.13388 30.3564C8.41002 29.8781 9.02161 29.7142 9.4999 29.9904C9.97819 30.2665 10.1421 30.8781 9.86593 31.3564Z" />
<path d="M1 18.0001C0.447715 18.0001 -3.44684e-08 17.5524 0 17.0001C3.44684e-08 16.4478 0.447715 16.0001 1 16.0001C1.55228 16.0001 2 16.4478 2 17.0001C2 17.5524 1.55228 18.0001 1 18.0001Z" />
<path d="M3.64329 25.866C3.16499 26.1422 2.5534 25.9783 2.27726 25.5C2.00112 25.0217 2.16499 24.4101 2.64329 24.134C3.12158 23.8578 3.73317 24.0217 4.00931 24.5C4.28545 24.9783 4.12158 25.5899 3.64329 25.866Z" />
<path d="M2.6435 9.86602C2.1652 9.58987 2.00133 8.97828 2.27747 8.49999C2.55361 8.0217 3.1652 7.85782 3.6435 8.13397C4.12179 8.41011 4.28566 9.0217 4.00952 9.49999C3.73338 9.97828 3.12179 10.1422 2.6435 9.86602Z" />
<path d="M16.0001 1C16.0001 0.447715 16.4478 -4.87226e-08 17.0001 0C17.5524 4.87226e-08 18.0001 0.447715 18.0001 1C18.0001 1.55228 17.5524 2 17.0001 2C16.4478 2 16.0001 1.55228 16.0001 1Z" />
<path d="M8.13398 3.64371C7.85783 3.16542 8.02171 2.55383 8.5 2.27768C8.97829 2.00154 9.58988 2.16542 9.86603 2.64371C10.1422 3.122 9.97829 3.73359 9.5 4.00973C9.02171 4.28588 8.41012 4.122 8.13398 3.64371Z" />
</svg>
)
}

View File

@ -0,0 +1,41 @@
import clsx from "clsx"
export type HeadingProps = {
as?: 'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
dark?: boolean
} & React.ComponentPropsWithoutRef<'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'>
export function Heading({ className, as: Element = 'h2', dark = false, ...props }: HeadingProps) {
return (
<Element
{...props}
data-dark={dark ? 'true' : undefined}
className={clsx(
className,
'text-4xl font-medium tracking-tighter text-pretty text-gray-950 dark:text-white sm:text-6xl',
)}
/>
)
}
export function Subheading({
className,
as: Element = 'h2',
dark = false,
...props
}: HeadingProps) {
return (
<Element
{...props}
data-dark={dark ? 'true' : undefined}
className={clsx(
className,
'font-mono text-xs/5 font-semibold tracking-widest text-gray-500 uppercase dark:text-gray-400',
)}
/>
)
}
export function Lead({ className, ...props }: React.ComponentPropsWithoutRef<'p'>) {
return <p className={clsx(className, 'text-2xl font-medium text-gray-500')} {...props} />
}

View File

@ -18,6 +18,8 @@ type CMSLinkType = {
size?: ButtonProps['size'] | null
type?: 'custom' | 'reference' | null
url?: string | null
backgroundColor?: string | null
textColor?: string | null
}
export const CMSLink: React.FC<CMSLinkType> = (props) => {
@ -31,6 +33,8 @@ export const CMSLink: React.FC<CMSLinkType> = (props) => {
reference,
size: sizeFromProps,
url,
backgroundColor,
textColor,
} = props
const href =
@ -56,8 +60,19 @@ export const CMSLink: React.FC<CMSLinkType> = (props) => {
}
return (
<Button asChild className={className} size={size} variant={appearance}>
<Link className={cn(className)} href={href || url || ''} {...newTabProps}>
<Button
asChild
className={cn(className, !!backgroundColor && `bg-[${backgroundColor}]`)}
size={size}
variant={appearance}
style={{ backgroundColor: backgroundColor || '' }}
>
<Link
className={cn(className, !!textColor && `text-[${textColor}]`, 'inline-block')}
href={href || url || ''}
{...newTabProps}
style={{ color: textColor || '' }}
>
{label && label}
{children && children}
</Link>

View File

@ -1,4 +1,3 @@
import clsx from 'clsx'
import React from 'react'
interface Props {
@ -8,7 +7,7 @@ interface Props {
}
export const Logo = (props: Props) => {
const { loading: loadingFromProps, priority: priorityFromProps, className } = props
const { loading: loadingFromProps, priority: priorityFromProps } = props
const loading = loadingFromProps || 'lazy'
const priority = priorityFromProps || 'low'
@ -16,14 +15,14 @@ export const Logo = (props: Props) => {
return (
/* eslint-disable @next/next/no-img-element */
<img
alt="Payload Logo"
alt="Beitzah Logo"
width={193}
height={34}
loading={loading}
fetchPriority={priority}
decoding="async"
className={clsx('max-w-[9.375rem] w-full h-[34px]', className)}
src="https://raw.githubusercontent.com/payloadcms/payload/main/packages/ui/src/assets/payload-logo-light.svg"
className={'max-w-[36px] w-full '}
src="https://cdn.beitzah.net/beitzah-egg.svg"
/>
)
}

View File

@ -35,7 +35,8 @@ const internalDocToHref = ({ linkNode }: { linkNode: SerializedLinkNode }) => {
return relationTo === 'posts' ? `/posts/${slug}` : `/${slug}`
}
const jsxConverters: JSXConvertersFunction<NodeTypes> = ({ defaultConverters }) => ({
const jsxConverters: JSXConvertersFunction<NodeTypes> = ({ defaultConverters }) => {
return {
...defaultConverters,
...LinkJSXConverter({ internalDocToHref }),
blocks: {
@ -53,7 +54,8 @@ const jsxConverters: JSXConvertersFunction<NodeTypes> = ({ defaultConverters })
code: ({ node }) => <CodeBlock className="col-start-2" {...node.fields} />,
cta: ({ node }) => <CallToActionBlock {...node.fields} />,
},
})
}
}
type Props = {
data: DefaultTypedEditorState

View File

@ -19,11 +19,13 @@ const buttonVariants = cva(
sm: 'h-9 rounded px-3',
},
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
default:
'inline-flex items-center justify-center px-4 py-[calc(--spacing(2)-1px)] rounded-full border border-transparent bg-gray-950 shadow-md text-base font-medium whitespace-nowrap text-white data-disabled:bg-gray-950 data-disabled:opacity-40 data-hover:bg-gray-800',
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
ghost: 'hover:bg-card hover:text-accent-foreground',
link: 'text-primary items-start justify-start underline-offset-4 hover:underline',
outline: 'border border-border bg-background hover:bg-card hover:text-accent-foreground',
outline:
'relative inline-flex items-center justify-center px-4 py-[calc(--spacing(2)-1px)] rounded-full border border-transparent bg-white/15 ring-1 shadow-md ring-[#D15052]/15 after:absolute after:inset-0 after:rounded-full after:shadow-[inset_0_0_2px_1px_#ffffff4d] text-base font-medium whitespace-nowrap text-gray-950 data-disabled:bg-white/15 data-disabled:opacity-40 data-hover:bg-white/20',
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
},
},
@ -46,7 +48,7 @@ const Button: React.FC<ButtonProps> = ({
...props
}) => {
const Comp = asChild ? Slot : 'button'
return <Comp className={cn(buttonVariants({ className, size, variant }))} ref={ref} {...props} />
return <Comp className={cn(buttonVariants({ size, variant, className }))} ref={ref} {...props} />
}
export { Button, buttonVariants }

View File

@ -7,6 +7,9 @@ import {
lexicalEditor,
UnderlineFeature,
type LinkFields,
UnorderedListFeature,
AlignFeature,
BlockquoteFeature,
} from '@payloadcms/richtext-lexical'
export const defaultLexical = lexicalEditor({
@ -15,6 +18,9 @@ export const defaultLexical = lexicalEditor({
UnderlineFeature(),
BoldFeature(),
ItalicFeature(),
AlignFeature(),
BlockquoteFeature(),
UnorderedListFeature(),
LinkFeature({
enabledCollections: ['pages', 'posts'],
fields: ({ defaultFields }) => {

View File

@ -2,7 +2,7 @@ import type { Field, GroupField } from 'payload'
import deepMerge from '@/utilities/deepMerge'
export type LinkAppearances = 'default' | 'outline'
export type LinkAppearances = 'default' | 'outline' | 'destructive'
export const appearanceOptions: Record<LinkAppearances, { label: string; value: string }> = {
default: {
@ -13,6 +13,10 @@ export const appearanceOptions: Record<LinkAppearances, { label: string; value:
label: 'Outline',
value: 'outline',
},
destructive: {
label: 'Destructive',
value: 'destructive',
},
}
type LinkType = (options?: {
@ -62,6 +66,14 @@ export const link: LinkType = ({ appearances, disableLabel = false, overrides =
},
label: 'Open in new tab',
},
{
name: 'backgroundColor',
type: 'text',
},
{
name: 'textColor',
type: 'text',
},
],
},
],

View File

@ -0,0 +1,42 @@
'use client'
import { useHeaderTheme } from '@/providers/HeaderTheme'
import React, { useEffect } from 'react'
import type { Page } from '@/payload-types'
import { CMSLink } from '@/components/Link'
import RichText from '@/components/RichText'
export const GradientImpactHero: React.FC<Page['hero']> = ({ links, richText }) => {
const { setHeaderTheme } = useHeaderTheme()
useEffect(() => {
setHeaderTheme('light')
})
return (
<div
className="relative -mt-[10.4rem] flex items-center justify-center min-h-[80vh] text-white h-48 bg-gradient-to-br from-[#fff1be] from-12% via-[#ee87cb] via-40% to-[#2e296b] rounded-b-3xl"
data-theme="dark"
>
<div className="container mb-8 z-10 relative flex items-center justify-center">
<div className="mx-auto w-full lg:max-w-7xl text-left">
{richText && (
<RichText className="mb-6 text-white" data={richText} enableGutter={false} />
)}
{Array.isArray(links) && links.length > 0 && (
<ul className="flex md:justify-left gap-4">
{links.map(({ link }, i) => {
return (
<li key={i}>
<CMSLink {...link} />
</li>
)
})}
</ul>
)}
</div>
</div>
</div>
)
}

View File

@ -2,11 +2,13 @@ import React from 'react'
import type { Page } from '@/payload-types'
import { GradientImpactHero } from '@/heros/GradientImpact'
import { HighImpactHero } from '@/heros/HighImpact'
import { LowImpactHero } from '@/heros/LowImpact'
import { MediumImpactHero } from '@/heros/MediumImpact'
const heroes = {
gradientImpact: GradientImpactHero,
highImpact: HighImpactHero,
lowImpact: LowImpactHero,
mediumImpact: MediumImpactHero,

View File

@ -23,6 +23,10 @@ export const hero: Field = {
label: 'None',
value: 'none',
},
{
label: 'Gradient Impact',
value: 'gradientImpact',
},
{
label: 'High Impact',
value: 'highImpact',

View File

@ -54,6 +54,7 @@ export type SupportedTimezones =
| 'Asia/Singapore'
| 'Asia/Tokyo'
| 'Asia/Seoul'
| 'Australia/Brisbane'
| 'Australia/Sydney'
| 'Pacific/Guam'
| 'Pacific/Noumea'
@ -97,7 +98,7 @@ export interface Config {
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
};
db: {
defaultIDType: string;
defaultIDType: number;
};
globals: {
header: Header;
@ -145,10 +146,10 @@ export interface UserAuthOperations {
* via the `definition` "pages".
*/
export interface Page {
id: string;
id: number;
title: string;
hero: {
type: 'none' | 'highImpact' | 'mediumImpact' | 'lowImpact';
type: 'none' | 'gradientImpact' | 'highImpact' | 'mediumImpact' | 'lowImpact';
richText?: {
root: {
type: string;
@ -169,14 +170,16 @@ export interface Page {
link: {
type?: ('reference' | 'custom') | null;
newTab?: boolean | null;
backgroundColor?: string | null;
textColor?: string | null;
reference?:
| ({
relationTo: 'pages';
value: string | Page;
value: number | Page;
} | null)
| ({
relationTo: 'posts';
value: string | Post;
value: number | Post;
} | null);
url?: string | null;
label: string;
@ -188,15 +191,15 @@ export interface Page {
id?: string | null;
}[]
| null;
media?: (string | null) | Media;
media?: (number | null) | Media;
};
layout: (CallToActionBlock | ContentBlock | MediaBlock | ArchiveBlock | FormBlock)[];
layout: (CallToActionBlock | ContentBlock | MediaBlock | ArchiveBlock | FormBlock | BentoBlock | ArticleBlock)[];
meta?: {
title?: string | null;
/**
* Maximum upload file size: 12MB. Recommended file size for images is <500KB.
*/
image?: (string | null) | Media;
image?: (number | null) | Media;
description?: string | null;
};
publishedAt?: string | null;
@ -211,9 +214,9 @@ export interface Page {
* via the `definition` "posts".
*/
export interface Post {
id: string;
id: number;
title: string;
heroImage?: (string | null) | Media;
heroImage?: (number | null) | Media;
content: {
root: {
type: string;
@ -229,18 +232,18 @@ export interface Post {
};
[k: string]: unknown;
};
relatedPosts?: (string | Post)[] | null;
categories?: (string | Category)[] | null;
relatedPosts?: (number | Post)[] | null;
categories?: (number | Category)[] | null;
meta?: {
title?: string | null;
/**
* Maximum upload file size: 12MB. Recommended file size for images is <500KB.
*/
image?: (string | null) | Media;
image?: (number | null) | Media;
description?: string | null;
};
publishedAt?: string | null;
authors?: (string | User)[] | null;
authors?: (number | User)[] | null;
populatedAuthors?:
| {
id?: string | null;
@ -258,7 +261,7 @@ export interface Post {
* via the `definition` "media".
*/
export interface Media {
id: string;
id: number;
alt?: string | null;
caption?: {
root: {
@ -350,14 +353,14 @@ export interface Media {
* via the `definition` "categories".
*/
export interface Category {
id: string;
id: number;
title: string;
slug?: string | null;
slugLock?: boolean | null;
parent?: (string | null) | Category;
parent?: (number | null) | Category;
breadcrumbs?:
| {
doc?: (string | null) | Category;
doc?: (number | null) | Category;
url?: string | null;
label?: string | null;
id?: string | null;
@ -371,7 +374,7 @@ export interface Category {
* via the `definition` "users".
*/
export interface User {
id: string;
id: number;
name?: string | null;
updatedAt: string;
createdAt: string;
@ -409,14 +412,16 @@ export interface CallToActionBlock {
link: {
type?: ('reference' | 'custom') | null;
newTab?: boolean | null;
backgroundColor?: string | null;
textColor?: string | null;
reference?:
| ({
relationTo: 'pages';
value: string | Page;
value: number | Page;
} | null)
| ({
relationTo: 'posts';
value: string | Post;
value: number | Post;
} | null);
url?: string | null;
label: string;
@ -459,14 +464,16 @@ export interface ContentBlock {
link?: {
type?: ('reference' | 'custom') | null;
newTab?: boolean | null;
backgroundColor?: string | null;
textColor?: string | null;
reference?:
| ({
relationTo: 'pages';
value: string | Page;
value: number | Page;
} | null)
| ({
relationTo: 'posts';
value: string | Post;
value: number | Post;
} | null);
url?: string | null;
label: string;
@ -478,6 +485,8 @@ export interface ContentBlock {
id?: string | null;
}[]
| null;
backgroundImage?: string | null;
isFullscreen?: boolean | null;
id?: string | null;
blockName?: string | null;
blockType: 'content';
@ -487,7 +496,7 @@ export interface ContentBlock {
* via the `definition` "MediaBlock".
*/
export interface MediaBlock {
media: string | Media;
media: number | Media;
id?: string | null;
blockName?: string | null;
blockType: 'mediaBlock';
@ -514,12 +523,12 @@ export interface ArchiveBlock {
} | null;
populateBy?: ('collection' | 'selection') | null;
relationTo?: 'posts' | null;
categories?: (string | Category)[] | null;
categories?: (number | Category)[] | null;
limit?: number | null;
selectedDocs?:
| {
relationTo: 'posts';
value: string | Post;
value: number | Post;
}[]
| null;
id?: string | null;
@ -531,7 +540,7 @@ export interface ArchiveBlock {
* via the `definition` "FormBlock".
*/
export interface FormBlock {
form: string | Form;
form: number | Form;
enableIntro?: boolean | null;
introContent?: {
root: {
@ -557,7 +566,7 @@ export interface FormBlock {
* via the `definition` "forms".
*/
export interface Form {
id: string;
id: number;
title: string;
fields?:
| (
@ -624,6 +633,7 @@ export interface Form {
label?: string | null;
width?: number | null;
defaultValue?: string | null;
placeholder?: string | null;
options?:
| {
label: string;
@ -725,12 +735,111 @@ export interface Form {
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "BentoBlock".
*/
export interface BentoBlock {
heading?: string | null;
subheading?: string | null;
graphics?:
| {
graphic?: ('animatedMapPins' | 'animatedLogoCluster' | 'animatedKeyboard') | null;
eyebrow?: string | null;
title?: string | null;
description?: string | null;
className?: string | null;
id?: string | null;
}[]
| null;
id?: string | null;
blockName?: string | null;
blockType: 'bento';
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "ArticleBlock".
*/
export interface ArticleBlock {
heading?: string | null;
subheading?: string | null;
brief?: {
root: {
type: string;
children: {
type: string;
version: number;
[k: string]: unknown;
}[];
direction: ('ltr' | 'rtl') | null;
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
indent: number;
version: number;
};
[k: string]: unknown;
} | null;
columns?:
| {
size?: ('oneThird' | 'half' | 'twoThirds' | 'full') | null;
richText?: {
root: {
type: string;
children: {
type: string;
version: number;
[k: string]: unknown;
}[];
direction: ('ltr' | 'rtl') | null;
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
indent: number;
version: number;
};
[k: string]: unknown;
} | null;
enableLink?: boolean | null;
link?: {
type?: ('reference' | 'custom') | null;
newTab?: boolean | null;
backgroundColor?: string | null;
textColor?: string | null;
reference?:
| ({
relationTo: 'pages';
value: number | Page;
} | null)
| ({
relationTo: 'posts';
value: number | Post;
} | null);
url?: string | null;
label: string;
/**
* Choose how the link should be rendered.
*/
appearance?: ('default' | 'outline') | null;
};
imageUrls?:
| {
url?: string | null;
alt?: string | null;
width?: number | null;
height?: number | null;
id?: string | null;
}[]
| null;
id?: string | null;
}[]
| null;
id?: string | null;
blockName?: string | null;
blockType: 'article';
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "redirects".
*/
export interface Redirect {
id: string;
id: number;
/**
* You will need to rebuild the website when changing this field.
*/
@ -740,11 +849,11 @@ export interface Redirect {
reference?:
| ({
relationTo: 'pages';
value: string | Page;
value: number | Page;
} | null)
| ({
relationTo: 'posts';
value: string | Post;
value: number | Post;
} | null);
url?: string | null;
};
@ -756,8 +865,8 @@ export interface Redirect {
* via the `definition` "form-submissions".
*/
export interface FormSubmission {
id: string;
form: string | Form;
id: number;
form: number | Form;
submissionData?:
| {
field: string;
@ -775,18 +884,18 @@ export interface FormSubmission {
* via the `definition` "search".
*/
export interface Search {
id: string;
id: number;
title?: string | null;
priority?: number | null;
doc: {
relationTo: 'posts';
value: string | Post;
value: number | Post;
};
slug?: string | null;
meta?: {
title?: string | null;
description?: string | null;
image?: (string | null) | Media;
image?: (number | null) | Media;
};
categories?:
| {
@ -803,7 +912,7 @@ export interface Search {
* via the `definition` "payload-jobs".
*/
export interface PayloadJob {
id: string;
id: number;
/**
* Input data provided to the job
*/
@ -895,52 +1004,52 @@ export interface PayloadJob {
* via the `definition` "payload-locked-documents".
*/
export interface PayloadLockedDocument {
id: string;
id: number;
document?:
| ({
relationTo: 'pages';
value: string | Page;
value: number | Page;
} | null)
| ({
relationTo: 'posts';
value: string | Post;
value: number | Post;
} | null)
| ({
relationTo: 'media';
value: string | Media;
value: number | Media;
} | null)
| ({
relationTo: 'categories';
value: string | Category;
value: number | Category;
} | null)
| ({
relationTo: 'users';
value: string | User;
value: number | User;
} | null)
| ({
relationTo: 'redirects';
value: string | Redirect;
value: number | Redirect;
} | null)
| ({
relationTo: 'forms';
value: string | Form;
value: number | Form;
} | null)
| ({
relationTo: 'form-submissions';
value: string | FormSubmission;
value: number | FormSubmission;
} | null)
| ({
relationTo: 'search';
value: string | Search;
value: number | Search;
} | null)
| ({
relationTo: 'payload-jobs';
value: string | PayloadJob;
value: number | PayloadJob;
} | null);
globalSlug?: string | null;
user: {
relationTo: 'users';
value: string | User;
value: number | User;
};
updatedAt: string;
createdAt: string;
@ -950,10 +1059,10 @@ export interface PayloadLockedDocument {
* via the `definition` "payload-preferences".
*/
export interface PayloadPreference {
id: string;
id: number;
user: {
relationTo: 'users';
value: string | User;
value: number | User;
};
key?: string | null;
value?:
@ -973,7 +1082,7 @@ export interface PayloadPreference {
* via the `definition` "payload-migrations".
*/
export interface PayloadMigration {
id: string;
id: number;
name?: string | null;
batch?: number | null;
updatedAt: string;
@ -998,6 +1107,8 @@ export interface PagesSelect<T extends boolean = true> {
| {
type?: T;
newTab?: T;
backgroundColor?: T;
textColor?: T;
reference?: T;
url?: T;
label?: T;
@ -1015,6 +1126,8 @@ export interface PagesSelect<T extends boolean = true> {
mediaBlock?: T | MediaBlockSelect<T>;
archive?: T | ArchiveBlockSelect<T>;
formBlock?: T | FormBlockSelect<T>;
bento?: T | BentoBlockSelect<T>;
article?: T | ArticleBlockSelect<T>;
};
meta?:
| T
@ -1044,6 +1157,8 @@ export interface CallToActionBlockSelect<T extends boolean = true> {
| {
type?: T;
newTab?: T;
backgroundColor?: T;
textColor?: T;
reference?: T;
url?: T;
label?: T;
@ -1070,6 +1185,8 @@ export interface ContentBlockSelect<T extends boolean = true> {
| {
type?: T;
newTab?: T;
backgroundColor?: T;
textColor?: T;
reference?: T;
url?: T;
label?: T;
@ -1077,6 +1194,8 @@ export interface ContentBlockSelect<T extends boolean = true> {
};
id?: T;
};
backgroundImage?: T;
isFullscreen?: T;
id?: T;
blockName?: T;
}
@ -1114,6 +1233,66 @@ export interface FormBlockSelect<T extends boolean = true> {
id?: T;
blockName?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "BentoBlock_select".
*/
export interface BentoBlockSelect<T extends boolean = true> {
heading?: T;
subheading?: T;
graphics?:
| T
| {
graphic?: T;
eyebrow?: T;
title?: T;
description?: T;
className?: T;
id?: T;
};
id?: T;
blockName?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "ArticleBlock_select".
*/
export interface ArticleBlockSelect<T extends boolean = true> {
heading?: T;
subheading?: T;
brief?: T;
columns?:
| T
| {
size?: T;
richText?: T;
enableLink?: T;
link?:
| T
| {
type?: T;
newTab?: T;
backgroundColor?: T;
textColor?: T;
reference?: T;
url?: T;
label?: T;
appearance?: T;
};
imageUrls?:
| T
| {
url?: T;
alt?: T;
width?: T;
height?: T;
id?: T;
};
id?: T;
};
id?: T;
blockName?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "posts_select".
@ -1355,6 +1534,7 @@ export interface FormsSelect<T extends boolean = true> {
label?: T;
width?: T;
defaultValue?: T;
placeholder?: T;
options?:
| T
| {
@ -1532,20 +1712,22 @@ export interface PayloadMigrationsSelect<T extends boolean = true> {
* via the `definition` "header".
*/
export interface Header {
id: string;
id: number;
navItems?:
| {
link: {
type?: ('reference' | 'custom') | null;
newTab?: boolean | null;
backgroundColor?: string | null;
textColor?: string | null;
reference?:
| ({
relationTo: 'pages';
value: string | Page;
value: number | Page;
} | null)
| ({
relationTo: 'posts';
value: string | Post;
value: number | Post;
} | null);
url?: string | null;
label: string;
@ -1561,20 +1743,22 @@ export interface Header {
* via the `definition` "footer".
*/
export interface Footer {
id: string;
id: number;
navItems?:
| {
link: {
type?: ('reference' | 'custom') | null;
newTab?: boolean | null;
backgroundColor?: string | null;
textColor?: string | null;
reference?:
| ({
relationTo: 'pages';
value: string | Page;
value: number | Page;
} | null)
| ({
relationTo: 'posts';
value: string | Post;
value: number | Post;
} | null);
url?: string | null;
label: string;
@ -1598,6 +1782,8 @@ export interface HeaderSelect<T extends boolean = true> {
| {
type?: T;
newTab?: T;
backgroundColor?: T;
textColor?: T;
reference?: T;
url?: T;
label?: T;
@ -1621,6 +1807,8 @@ export interface FooterSelect<T extends boolean = true> {
| {
type?: T;
newTab?: T;
backgroundColor?: T;
textColor?: T;
reference?: T;
url?: T;
label?: T;
@ -1642,14 +1830,14 @@ export interface TaskSchedulePublish {
doc?:
| ({
relationTo: 'pages';
value: string | Page;
value: number | Page;
} | null)
| ({
relationTo: 'posts';
value: string | Post;
value: number | Post;
} | null);
global?: string | null;
user?: (string | null) | User;
user?: (number | null) | User;
};
output?: unknown;
}

View File

@ -116,6 +116,11 @@ const config = {
h1: {
fontWeight: 'normal',
marginBottom: '0.25em',
fontSize: '3.5rem',
},
h3: {
fontSize: '1.25rem',
fontWeight: 400,
},
},
],
@ -124,7 +129,7 @@ const config = {
css: [
{
h1: {
fontSize: '2.5rem',
fontSize: '3.5rem',
},
h2: {
fontSize: '1.25rem',
@ -137,7 +142,7 @@ const config = {
css: [
{
h1: {
fontSize: '3.5rem',
fontSize: '4.5rem',
},
h2: {
fontSize: '1.5rem',