removed tsconfig.json
This commit is contained in:
@ -1,4 +1,20 @@
|
|||||||
/** @type {import('next').NextConfig} */
|
// import { withPayload } from "@payloadcms/next/withPayload";
|
||||||
const nextConfig = {};
|
// /** @type {import('next').NextConfig} */
|
||||||
|
// const nextConfig = {};
|
||||||
|
|
||||||
export default nextConfig;
|
// export default withPayload(nextConfig);
|
||||||
|
|
||||||
|
|
||||||
|
import { withPayload } from '@payloadcms/next/withPayload'
|
||||||
|
|
||||||
|
/** @type {import('next').NextConfig} */
|
||||||
|
const nextConfig = {
|
||||||
|
// Your Next.js config here
|
||||||
|
experimental: {
|
||||||
|
reactCompiler: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure you wrap your `nextConfig`
|
||||||
|
// with the `withPayload` plugin
|
||||||
|
export default withPayload(nextConfig)
|
||||||
17
package.json
17
package.json
@ -9,19 +9,28 @@
|
|||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@payloadcms/db-mongodb": "^3.54.0",
|
||||||
|
"@payloadcms/next": "^3.54.0",
|
||||||
|
"@payloadcms/payload-cloud": "^3.54.0",
|
||||||
|
"@payloadcms/richtext-lexical": "^3.54.0",
|
||||||
"bootstrap": "^5.3.3",
|
"bootstrap": "^5.3.3",
|
||||||
"next": "14.1.4",
|
"graphql": "^16.11.0",
|
||||||
"react": "^18",
|
"next": "15.5.2",
|
||||||
|
"payload": "^3.54.0",
|
||||||
|
"react": "^18.3.1",
|
||||||
"react-countup": "^6.5.2",
|
"react-countup": "^6.5.2",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18.3.1",
|
||||||
"react-icons": "^5.5.0",
|
"react-icons": "^5.5.0",
|
||||||
|
"react-intersection-observer": "^9.16.0",
|
||||||
"react-modal-video": "^2.0.1",
|
"react-modal-video": "^2.0.1",
|
||||||
"react-scroll-trigger": "^0.6.14",
|
"react-scroll-trigger": "^0.6.14",
|
||||||
"react-skillbars": "^2.2.0",
|
"react-skillbars": "^2.2.0",
|
||||||
|
"sharp": "^0.34.3",
|
||||||
"swiper": "^11.0.7"
|
"swiper": "^11.0.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "24.3.0",
|
"@types/node": "24.3.0",
|
||||||
"typescript": "5.9.2"
|
"typescript": "5.9.2"
|
||||||
}
|
},
|
||||||
|
"type": "module"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import ErrorPage from '@/src/components/pages/error';
|
import ErrorPage from '@/components/pages/error';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const NotFound = () => {
|
const NotFound = () => {
|
||||||
|
|||||||
48
src/app/(frontend)/layout.tsx
Normal file
48
src/app/(frontend)/layout.tsx
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// import React from 'react'
|
||||||
|
// import './styles.css'
|
||||||
|
|
||||||
|
// export const metadata = {
|
||||||
|
// description: 'A blank template using Payload in a Next.js app.',
|
||||||
|
// title: 'Payload Blank Template',
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export default async function RootLayout(props: { children: React.ReactNode }) {
|
||||||
|
// const { children } = props
|
||||||
|
|
||||||
|
// return (
|
||||||
|
// <html lang="en">
|
||||||
|
// <body>
|
||||||
|
// <main>{children}</main>
|
||||||
|
// </body>
|
||||||
|
// </html>
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
"use client"
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import "./globals.css";
|
||||||
|
import SwitchTab from '@/components/pages/common/dark-light';
|
||||||
|
//import SwitchTab from '../../pages/common/dark-light';
|
||||||
|
//import SwitchTab from '@/src/components/pages/common/dark-light';
|
||||||
|
|
||||||
|
//import SwitchTab from '@/src/components/pages/common/dark-light';
|
||||||
|
|
||||||
|
|
||||||
|
export default function RootLayout({ children }) {
|
||||||
|
useEffect(() => {
|
||||||
|
require('bootstrap/dist/js/bootstrap.min.js');
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<link rel='icon' type='image/png' href='../favicon.ico' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<SwitchTab addClass={undefined} />
|
||||||
|
{children}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
64
src/app/(frontend)/page.tsx
Normal file
64
src/app/(frontend)/page.tsx
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import { headers as getHeaders } from 'next/headers.js'
|
||||||
|
import Image from 'next/image'
|
||||||
|
import { getPayload } from 'payload'
|
||||||
|
import React from 'react'
|
||||||
|
import { fileURLToPath } from 'url'
|
||||||
|
|
||||||
|
import config from '@/payload.config'
|
||||||
|
import './styles.css'
|
||||||
|
|
||||||
|
import HomeOne from "@/components/pages/homes/home";
|
||||||
|
|
||||||
|
export default async function HomePage() {
|
||||||
|
const headers = await getHeaders()
|
||||||
|
const payloadConfig = await config
|
||||||
|
const payload = await getPayload({ config: payloadConfig })
|
||||||
|
const { user } = await payload.auth({ headers })
|
||||||
|
|
||||||
|
const fileURL = `vscode://file/${fileURLToPath(import.meta.url)}`
|
||||||
|
|
||||||
|
return (
|
||||||
|
// <div className="home">
|
||||||
|
// <div className="content">
|
||||||
|
// <picture>
|
||||||
|
// <source srcSet="https://raw.githubusercontent.com/payloadcms/payload/main/packages/ui/src/assets/payload-favicon.svg" />
|
||||||
|
// <Image
|
||||||
|
// alt="Payload Logo"
|
||||||
|
// height={65}
|
||||||
|
// src="https://raw.githubusercontent.com/payloadcms/payload/main/packages/ui/src/assets/payload-favicon.svg"
|
||||||
|
// width={65}
|
||||||
|
// />
|
||||||
|
// </picture>
|
||||||
|
// {!user && <h1>Welcome to your new project.</h1>}
|
||||||
|
// {user && <h1>Welcome back, {user.email}</h1>}
|
||||||
|
// <div className="links">
|
||||||
|
// <a
|
||||||
|
// className="admin"
|
||||||
|
// href={payloadConfig.routes.admin}
|
||||||
|
// rel="noopener noreferrer"
|
||||||
|
// target="_blank"
|
||||||
|
// >
|
||||||
|
// Go to admin panel
|
||||||
|
// </a>
|
||||||
|
// <a
|
||||||
|
// className="docs"
|
||||||
|
// href="https://payloadcms.com/docs"
|
||||||
|
// rel="noopener noreferrer"
|
||||||
|
// target="_blank"
|
||||||
|
// >
|
||||||
|
// Documentation
|
||||||
|
// </a>
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
// <div className="footer">
|
||||||
|
// <p>Update this page by editing</p>
|
||||||
|
// <a className="codeLink" href={fileURL}>
|
||||||
|
// <code>app/(frontend)/page.tsx</code>
|
||||||
|
// </a>
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
<>
|
||||||
|
<HomeOne />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
164
src/app/(frontend)/styles.css
Normal file
164
src/app/(frontend)/styles.css
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
:root {
|
||||||
|
--font-mono: 'Roboto Mono', monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 32px;
|
||||||
|
|
||||||
|
background: rgb(0, 0, 0);
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
#app {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: system-ui;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 32px;
|
||||||
|
|
||||||
|
margin: 0;
|
||||||
|
color: rgb(1000, 1000, 1000);
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin: 40px 0;
|
||||||
|
font-size: 64px;
|
||||||
|
line-height: 70px;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
margin: 24px 0;
|
||||||
|
font-size: 42px;
|
||||||
|
line-height: 42px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
font-size: 38px;
|
||||||
|
line-height: 38px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 400px) {
|
||||||
|
font-size: 32px;
|
||||||
|
line-height: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 24px 0;
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
margin: calc(var(--base) * 0.75) 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: currentColor;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
opacity: 0.8;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
opacity: 0.7;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 45px;
|
||||||
|
max-width: 1024px;
|
||||||
|
margin: 0 auto;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
@media (max-width: 400px) {
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.links {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin {
|
||||||
|
color: rgb(0, 0, 0);
|
||||||
|
background: rgb(1000, 1000, 1000);
|
||||||
|
border: 1px solid rgb(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.docs {
|
||||||
|
color: rgb(1000, 1000, 1000);
|
||||||
|
background: rgb(0, 0, 0);
|
||||||
|
border: 1px solid rgb(1000, 1000, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.codeLink {
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
background: rgb(60, 60, 60);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/app/my-route/route.ts
Normal file
12
src/app/my-route/route.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import configPromise from '@payload-config'
|
||||||
|
import { getPayload } from 'payload'
|
||||||
|
|
||||||
|
export const GET = async (request: Request) => {
|
||||||
|
const payload = await getPayload({
|
||||||
|
config: configPromise,
|
||||||
|
})
|
||||||
|
|
||||||
|
return Response.json({
|
||||||
|
message: 'This is an example of a custom route.',
|
||||||
|
})
|
||||||
|
}
|
||||||
0
src/blocks/ArchiveBlock/Component.tsx
Normal file
0
src/blocks/ArchiveBlock/Component.tsx
Normal file
1
src/blocks/ArchiveBlock/config.ts
Normal file
1
src/blocks/ArchiveBlock/config.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
0
src/blocks/Banner/Component.tsx
Normal file
0
src/blocks/Banner/Component.tsx
Normal file
0
src/blocks/Banner/config.ts
Normal file
0
src/blocks/Banner/config.ts
Normal file
23
src/blocks/CallToAction/Component.tsx
Normal file
23
src/blocks/CallToAction/Component.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import type { CallToActionBlock as CTABlockProps } from '@/payload-types'
|
||||||
|
|
||||||
|
import RichText from '@/components/RichText'
|
||||||
|
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>
|
||||||
|
<div className="flex flex-col gap-8">
|
||||||
|
{(links || []).map(({ link }, i) => {
|
||||||
|
return <CMSLink key={i} size="lg" {...link} />
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
42
src/blocks/CallToAction/config.ts
Normal file
42
src/blocks/CallToAction/config.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import type { Block } from 'payload'
|
||||||
|
|
||||||
|
import {
|
||||||
|
FixedToolbarFeature,
|
||||||
|
HeadingFeature,
|
||||||
|
InlineToolbarFeature,
|
||||||
|
lexicalEditor,
|
||||||
|
} from '@payloadcms/richtext-lexical'
|
||||||
|
|
||||||
|
import { linkGroup } from '../../fields/linkGroup'
|
||||||
|
|
||||||
|
export const CallToAction: Block = {
|
||||||
|
slug: 'cta',
|
||||||
|
interfaceName: 'CallToActionBlock',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'richText',
|
||||||
|
type: 'richText',
|
||||||
|
editor: lexicalEditor({
|
||||||
|
features: ({ rootFeatures }) => {
|
||||||
|
return [
|
||||||
|
...rootFeatures,
|
||||||
|
HeadingFeature({ enabledHeadingSizes: ['h1', 'h2', 'h3', 'h4'] }),
|
||||||
|
FixedToolbarFeature(),
|
||||||
|
InlineToolbarFeature(),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
label: false,
|
||||||
|
},
|
||||||
|
linkGroup({
|
||||||
|
appearances: ['default', 'outline'],
|
||||||
|
overrides: {
|
||||||
|
maxRows: 2,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
labels: {
|
||||||
|
plural: 'Calls to Action',
|
||||||
|
singular: 'Call to Action',
|
||||||
|
},
|
||||||
|
}
|
||||||
1
src/blocks/Code/Component.client.tsx
Normal file
1
src/blocks/Code/Component.client.tsx
Normal file
@ -0,0 +1 @@
|
|||||||
|
//
|
||||||
21
src/blocks/Code/Component.tsx
Normal file
21
src/blocks/Code/Component.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// import React from 'react'
|
||||||
|
|
||||||
|
// import { Code } from './Component.client'
|
||||||
|
|
||||||
|
// export type CodeBlockProps = {
|
||||||
|
// code: string
|
||||||
|
// language?: string
|
||||||
|
// blockType: 'code'
|
||||||
|
// }
|
||||||
|
|
||||||
|
// type Props = CodeBlockProps & {
|
||||||
|
// className?: string
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export const CodeBlock: React.FC<Props> = ({ className, code, language }) => {
|
||||||
|
// return (
|
||||||
|
// <div className={[className, 'not-prose'].filter(Boolean).join(' ')}>
|
||||||
|
// <Code code={code} language={language} />
|
||||||
|
// </div>
|
||||||
|
// )
|
||||||
|
// }
|
||||||
0
src/blocks/Code/CopyButton.tsx
Normal file
0
src/blocks/Code/CopyButton.tsx
Normal file
33
src/blocks/Code/config.ts
Normal file
33
src/blocks/Code/config.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import type { Block } from 'payload'
|
||||||
|
|
||||||
|
export const Code: Block = {
|
||||||
|
slug: 'code',
|
||||||
|
interfaceName: 'CodeBlock',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'language',
|
||||||
|
type: 'select',
|
||||||
|
defaultValue: 'typescript',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: 'Typescript',
|
||||||
|
value: 'typescript',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Javascript',
|
||||||
|
value: 'javascript',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'CSS',
|
||||||
|
value: 'css',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'code',
|
||||||
|
type: 'code',
|
||||||
|
label: false,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
0
src/blocks/Content/Component.tsx
Normal file
0
src/blocks/Content/Component.tsx
Normal file
82
src/blocks/Content/config.ts
Normal file
82
src/blocks/Content/config.ts
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
// import type { Block, Field } from 'payload'
|
||||||
|
|
||||||
|
// import {
|
||||||
|
// FixedToolbarFeature,
|
||||||
|
// HeadingFeature,
|
||||||
|
// InlineToolbarFeature,
|
||||||
|
// lexicalEditor,
|
||||||
|
// } from '@payloadcms/richtext-lexical'
|
||||||
|
|
||||||
|
// import { link } from '@/fields/link'
|
||||||
|
|
||||||
|
// 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: ({ rootFeatures }) => {
|
||||||
|
// return [
|
||||||
|
// ...rootFeatures,
|
||||||
|
// HeadingFeature({ enabledHeadingSizes: ['h2', 'h3', 'h4'] }),
|
||||||
|
// FixedToolbarFeature(),
|
||||||
|
// InlineToolbarFeature(),
|
||||||
|
// ]
|
||||||
|
// },
|
||||||
|
// }),
|
||||||
|
// label: false,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: 'enableLink',
|
||||||
|
// type: 'checkbox',
|
||||||
|
// },
|
||||||
|
// link({
|
||||||
|
// overrides: {
|
||||||
|
// admin: {
|
||||||
|
// condition: (_data, siblingData) => {
|
||||||
|
// return Boolean(siblingData?.enableLink)
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// }),
|
||||||
|
// ]
|
||||||
|
|
||||||
|
// export const Content: Block = {
|
||||||
|
// slug: 'content',
|
||||||
|
// interfaceName: 'ContentBlock',
|
||||||
|
// fields: [
|
||||||
|
// {
|
||||||
|
// name: 'columns',
|
||||||
|
// type: 'array',
|
||||||
|
// admin: {
|
||||||
|
// initCollapsed: true,
|
||||||
|
// },
|
||||||
|
// fields: columnFields,
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
45
src/blocks/Form/Checkbox/index.tsx
Normal file
45
src/blocks/Form/Checkbox/index.tsx
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import type { CheckboxField } from '@payloadcms/plugin-form-builder/types'
|
||||||
|
import type { FieldErrorsImpl, FieldValues, UseFormRegister } from 'react-hook-form'
|
||||||
|
|
||||||
|
import { useFormContext } from 'react-hook-form'
|
||||||
|
|
||||||
|
import { Checkbox as CheckboxUi } from '@/components/ui/checkbox'
|
||||||
|
import { Label } from '@/components/ui/label'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import { Error } from '../Error'
|
||||||
|
import { Width } from '../Width'
|
||||||
|
|
||||||
|
export const Checkbox: React.FC<
|
||||||
|
CheckboxField & {
|
||||||
|
errors: Partial<FieldErrorsImpl>
|
||||||
|
register: UseFormRegister<FieldValues>
|
||||||
|
}
|
||||||
|
> = ({ name, defaultValue, errors, label, register, required, width }) => {
|
||||||
|
const props = register(name, { required: required })
|
||||||
|
const { setValue } = useFormContext()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Width width={width}>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<CheckboxUi
|
||||||
|
defaultChecked={defaultValue}
|
||||||
|
id={name}
|
||||||
|
{...props}
|
||||||
|
onCheckedChange={(checked) => {
|
||||||
|
setValue(props.name, checked)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Label htmlFor={name}>
|
||||||
|
{required && (
|
||||||
|
<span className="required">
|
||||||
|
* <span className="sr-only">(required)</span>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{label}
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
|
{errors[name] && <Error name={name} />}
|
||||||
|
</Width>
|
||||||
|
)
|
||||||
|
}
|
||||||
163
src/blocks/Form/Component.tsx
Normal file
163
src/blocks/Form/Component.tsx
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
'use client'
|
||||||
|
import type { FormFieldBlock, Form as FormType } from '@payloadcms/plugin-form-builder/types'
|
||||||
|
|
||||||
|
import { useRouter } from 'next/navigation'
|
||||||
|
import React, { useCallback, useState } from 'react'
|
||||||
|
import { useForm, FormProvider } from 'react-hook-form'
|
||||||
|
import RichText from '@/components/RichText'
|
||||||
|
import { Button } from '@/components/ui/button'
|
||||||
|
import type { SerializedEditorState } from '@payloadcms/richtext-lexical/lexical'
|
||||||
|
|
||||||
|
import { fields } from './fields'
|
||||||
|
import { getClientSideURL } from '@/utilities/getURL'
|
||||||
|
|
||||||
|
export type FormBlockType = {
|
||||||
|
blockName?: string
|
||||||
|
blockType?: 'formBlock'
|
||||||
|
enableIntro: boolean
|
||||||
|
form: FormType
|
||||||
|
introContent?: SerializedEditorState
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FormBlock: React.FC<
|
||||||
|
{
|
||||||
|
id?: string
|
||||||
|
} & FormBlockType
|
||||||
|
> = (props) => {
|
||||||
|
const {
|
||||||
|
enableIntro,
|
||||||
|
form: formFromProps,
|
||||||
|
form: { id: formID, confirmationMessage, confirmationType, redirect, submitButtonLabel } = {},
|
||||||
|
introContent,
|
||||||
|
} = props
|
||||||
|
|
||||||
|
const formMethods = useForm({
|
||||||
|
defaultValues: formFromProps.fields,
|
||||||
|
})
|
||||||
|
const {
|
||||||
|
control,
|
||||||
|
formState: { errors },
|
||||||
|
handleSubmit,
|
||||||
|
register,
|
||||||
|
} = formMethods
|
||||||
|
|
||||||
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
|
const [hasSubmitted, setHasSubmitted] = useState<boolean>()
|
||||||
|
const [error, setError] = useState<{ message: string; status?: string } | undefined>()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const onSubmit = useCallback(
|
||||||
|
(data: FormFieldBlock[]) => {
|
||||||
|
let loadingTimerID: ReturnType<typeof setTimeout>
|
||||||
|
const submitForm = async () => {
|
||||||
|
setError(undefined)
|
||||||
|
|
||||||
|
const dataToSend = Object.entries(data).map(([name, value]) => ({
|
||||||
|
field: name,
|
||||||
|
value,
|
||||||
|
}))
|
||||||
|
|
||||||
|
// delay loading indicator by 1s
|
||||||
|
loadingTimerID = setTimeout(() => {
|
||||||
|
setIsLoading(true)
|
||||||
|
}, 1000)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const req = await fetch(`${getClientSideURL()}/api/form-submissions`, {
|
||||||
|
body: JSON.stringify({
|
||||||
|
form: formID,
|
||||||
|
submissionData: dataToSend,
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
method: 'POST',
|
||||||
|
})
|
||||||
|
|
||||||
|
const res = await req.json()
|
||||||
|
|
||||||
|
clearTimeout(loadingTimerID)
|
||||||
|
|
||||||
|
if (req.status >= 400) {
|
||||||
|
setIsLoading(false)
|
||||||
|
|
||||||
|
setError({
|
||||||
|
message: res.errors?.[0]?.message || 'Internal Server Error',
|
||||||
|
status: res.status,
|
||||||
|
})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsLoading(false)
|
||||||
|
setHasSubmitted(true)
|
||||||
|
|
||||||
|
if (confirmationType === 'redirect' && redirect) {
|
||||||
|
const { url } = redirect
|
||||||
|
|
||||||
|
const redirectUrl = url
|
||||||
|
|
||||||
|
if (redirectUrl) router.push(redirectUrl)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.warn(err)
|
||||||
|
setIsLoading(false)
|
||||||
|
setError({
|
||||||
|
message: 'Something went wrong.',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void submitForm()
|
||||||
|
},
|
||||||
|
[router, formID, redirect, confirmationType],
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container lg:max-w-[48rem]">
|
||||||
|
{enableIntro && introContent && !hasSubmitted && (
|
||||||
|
<RichText className="mb-8 lg:mb-12" data={introContent} enableGutter={false} />
|
||||||
|
)}
|
||||||
|
<div className="p-4 lg:p-6 border border-border rounded-[0.8rem]">
|
||||||
|
<FormProvider {...formMethods}>
|
||||||
|
{!isLoading && hasSubmitted && confirmationType === 'message' && (
|
||||||
|
<RichText data={confirmationMessage} />
|
||||||
|
)}
|
||||||
|
{isLoading && !hasSubmitted && <p>Loading, please wait...</p>}
|
||||||
|
{error && <div>{`${error.status || '500'}: ${error.message || ''}`}</div>}
|
||||||
|
{!hasSubmitted && (
|
||||||
|
<form id={formID} onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<div className="mb-4 last:mb-0">
|
||||||
|
{formFromProps &&
|
||||||
|
formFromProps.fields &&
|
||||||
|
formFromProps.fields?.map((field, index) => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const Field: React.FC<any> = fields?.[field.blockType as keyof typeof fields]
|
||||||
|
if (Field) {
|
||||||
|
return (
|
||||||
|
<div className="mb-6 last:mb-0" key={index}>
|
||||||
|
<Field
|
||||||
|
form={formFromProps}
|
||||||
|
{...field}
|
||||||
|
{...formMethods}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
register={register}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Button form={formID} type="submit" variant="default">
|
||||||
|
{submitButtonLabel}
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
)}
|
||||||
|
</FormProvider>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
65
src/blocks/Form/Country/index.tsx
Normal file
65
src/blocks/Form/Country/index.tsx
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import type { CountryField } from '@payloadcms/plugin-form-builder/types'
|
||||||
|
import type { Control, FieldErrorsImpl } from 'react-hook-form'
|
||||||
|
|
||||||
|
import { Label } from '@/components/ui/label'
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from '@/components/ui/select'
|
||||||
|
import React from 'react'
|
||||||
|
import { Controller } from 'react-hook-form'
|
||||||
|
|
||||||
|
import { Error } from '../Error'
|
||||||
|
import { Width } from '../Width'
|
||||||
|
import { countryOptions } from './options'
|
||||||
|
|
||||||
|
export const Country: React.FC<
|
||||||
|
CountryField & {
|
||||||
|
control: Control
|
||||||
|
errors: Partial<FieldErrorsImpl>
|
||||||
|
}
|
||||||
|
> = ({ name, control, errors, label, required, width }) => {
|
||||||
|
return (
|
||||||
|
<Width width={width}>
|
||||||
|
<Label className="" htmlFor={name}>
|
||||||
|
{label}
|
||||||
|
|
||||||
|
{required && (
|
||||||
|
<span className="required">
|
||||||
|
* <span className="sr-only">(required)</span>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</Label>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
defaultValue=""
|
||||||
|
name={name}
|
||||||
|
render={({ field: { onChange, value } }) => {
|
||||||
|
const controlledValue = countryOptions.find((t) => t.value === value)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Select onValueChange={(val) => onChange(val)} value={controlledValue?.value}>
|
||||||
|
<SelectTrigger className="w-full" id={name}>
|
||||||
|
<SelectValue placeholder={label} />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
{countryOptions.map(({ label, value }) => {
|
||||||
|
return (
|
||||||
|
<SelectItem key={value} value={value}>
|
||||||
|
{label}
|
||||||
|
</SelectItem>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
rules={{ required }}
|
||||||
|
/>
|
||||||
|
{errors[name] && <Error name={name} />}
|
||||||
|
</Width>
|
||||||
|
)
|
||||||
|
}
|
||||||
982
src/blocks/Form/Country/options.ts
Normal file
982
src/blocks/Form/Country/options.ts
Normal file
@ -0,0 +1,982 @@
|
|||||||
|
export const countryOptions = [
|
||||||
|
{
|
||||||
|
label: 'Afghanistan',
|
||||||
|
value: 'AF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Åland Islands',
|
||||||
|
value: 'AX',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Albania',
|
||||||
|
value: 'AL',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Algeria',
|
||||||
|
value: 'DZ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'American Samoa',
|
||||||
|
value: 'AS',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Andorra',
|
||||||
|
value: 'AD',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Angola',
|
||||||
|
value: 'AO',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Anguilla',
|
||||||
|
value: 'AI',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Antarctica',
|
||||||
|
value: 'AQ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Antigua and Barbuda',
|
||||||
|
value: 'AG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Argentina',
|
||||||
|
value: 'AR',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Armenia',
|
||||||
|
value: 'AM',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Aruba',
|
||||||
|
value: 'AW',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Australia',
|
||||||
|
value: 'AU',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Austria',
|
||||||
|
value: 'AT',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Azerbaijan',
|
||||||
|
value: 'AZ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Bahamas',
|
||||||
|
value: 'BS',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Bahrain',
|
||||||
|
value: 'BH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Bangladesh',
|
||||||
|
value: 'BD',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Barbados',
|
||||||
|
value: 'BB',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Belarus',
|
||||||
|
value: 'BY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Belgium',
|
||||||
|
value: 'BE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Belize',
|
||||||
|
value: 'BZ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Benin',
|
||||||
|
value: 'BJ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Bermuda',
|
||||||
|
value: 'BM',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Bhutan',
|
||||||
|
value: 'BT',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Bolivia',
|
||||||
|
value: 'BO',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Bosnia and Herzegovina',
|
||||||
|
value: 'BA',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Botswana',
|
||||||
|
value: 'BW',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Bouvet Island',
|
||||||
|
value: 'BV',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Brazil',
|
||||||
|
value: 'BR',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'British Indian Ocean Territory',
|
||||||
|
value: 'IO',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Brunei Darussalam',
|
||||||
|
value: 'BN',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Bulgaria',
|
||||||
|
value: 'BG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Burkina Faso',
|
||||||
|
value: 'BF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Burundi',
|
||||||
|
value: 'BI',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Cambodia',
|
||||||
|
value: 'KH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Cameroon',
|
||||||
|
value: 'CM',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Canada',
|
||||||
|
value: 'CA',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Cape Verde',
|
||||||
|
value: 'CV',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Cayman Islands',
|
||||||
|
value: 'KY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Central African Republic',
|
||||||
|
value: 'CF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Chad',
|
||||||
|
value: 'TD',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Chile',
|
||||||
|
value: 'CL',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'China',
|
||||||
|
value: 'CN',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Christmas Island',
|
||||||
|
value: 'CX',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Cocos (Keeling) Islands',
|
||||||
|
value: 'CC',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Colombia',
|
||||||
|
value: 'CO',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Comoros',
|
||||||
|
value: 'KM',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Congo',
|
||||||
|
value: 'CG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Congo, The Democratic Republic of the',
|
||||||
|
value: 'CD',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Cook Islands',
|
||||||
|
value: 'CK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Costa Rica',
|
||||||
|
value: 'CR',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Cote D'Ivoire",
|
||||||
|
value: 'CI',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Croatia',
|
||||||
|
value: 'HR',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Cuba',
|
||||||
|
value: 'CU',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Cyprus',
|
||||||
|
value: 'CY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Czech Republic',
|
||||||
|
value: 'CZ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Denmark',
|
||||||
|
value: 'DK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Djibouti',
|
||||||
|
value: 'DJ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Dominica',
|
||||||
|
value: 'DM',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Dominican Republic',
|
||||||
|
value: 'DO',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Ecuador',
|
||||||
|
value: 'EC',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Egypt',
|
||||||
|
value: 'EG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'El Salvador',
|
||||||
|
value: 'SV',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Equatorial Guinea',
|
||||||
|
value: 'GQ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Eritrea',
|
||||||
|
value: 'ER',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Estonia',
|
||||||
|
value: 'EE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Ethiopia',
|
||||||
|
value: 'ET',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Falkland Islands (Malvinas)',
|
||||||
|
value: 'FK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Faroe Islands',
|
||||||
|
value: 'FO',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Fiji',
|
||||||
|
value: 'FJ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Finland',
|
||||||
|
value: 'FI',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'France',
|
||||||
|
value: 'FR',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'French Guiana',
|
||||||
|
value: 'GF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'French Polynesia',
|
||||||
|
value: 'PF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'French Southern Territories',
|
||||||
|
value: 'TF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Gabon',
|
||||||
|
value: 'GA',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Gambia',
|
||||||
|
value: 'GM',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Georgia',
|
||||||
|
value: 'GE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Germany',
|
||||||
|
value: 'DE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Ghana',
|
||||||
|
value: 'GH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Gibraltar',
|
||||||
|
value: 'GI',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Greece',
|
||||||
|
value: 'GR',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Greenland',
|
||||||
|
value: 'GL',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Grenada',
|
||||||
|
value: 'GD',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Guadeloupe',
|
||||||
|
value: 'GP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Guam',
|
||||||
|
value: 'GU',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Guatemala',
|
||||||
|
value: 'GT',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Guernsey',
|
||||||
|
value: 'GG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Guinea',
|
||||||
|
value: 'GN',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Guinea-Bissau',
|
||||||
|
value: 'GW',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Guyana',
|
||||||
|
value: 'GY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Haiti',
|
||||||
|
value: 'HT',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Heard Island and Mcdonald Islands',
|
||||||
|
value: 'HM',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Holy See (Vatican City State)',
|
||||||
|
value: 'VA',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Honduras',
|
||||||
|
value: 'HN',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Hong Kong',
|
||||||
|
value: 'HK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Hungary',
|
||||||
|
value: 'HU',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Iceland',
|
||||||
|
value: 'IS',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'India',
|
||||||
|
value: 'IN',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Indonesia',
|
||||||
|
value: 'ID',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Iran, Islamic Republic Of',
|
||||||
|
value: 'IR',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Iraq',
|
||||||
|
value: 'IQ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Ireland',
|
||||||
|
value: 'IE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Isle of Man',
|
||||||
|
value: 'IM',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Israel',
|
||||||
|
value: 'IL',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Italy',
|
||||||
|
value: 'IT',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Jamaica',
|
||||||
|
value: 'JM',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Japan',
|
||||||
|
value: 'JP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Jersey',
|
||||||
|
value: 'JE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Jordan',
|
||||||
|
value: 'JO',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Kazakhstan',
|
||||||
|
value: 'KZ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Kenya',
|
||||||
|
value: 'KE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Kiribati',
|
||||||
|
value: 'KI',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Democratic People's Republic of Korea",
|
||||||
|
value: 'KP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Korea, Republic of',
|
||||||
|
value: 'KR',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Kosovo',
|
||||||
|
value: 'XK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Kuwait',
|
||||||
|
value: 'KW',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Kyrgyzstan',
|
||||||
|
value: 'KG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Lao People's Democratic Republic",
|
||||||
|
value: 'LA',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Latvia',
|
||||||
|
value: 'LV',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Lebanon',
|
||||||
|
value: 'LB',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Lesotho',
|
||||||
|
value: 'LS',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Liberia',
|
||||||
|
value: 'LR',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Libyan Arab Jamahiriya',
|
||||||
|
value: 'LY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Liechtenstein',
|
||||||
|
value: 'LI',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Lithuania',
|
||||||
|
value: 'LT',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Luxembourg',
|
||||||
|
value: 'LU',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Macao',
|
||||||
|
value: 'MO',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Macedonia, The Former Yugoslav Republic of',
|
||||||
|
value: 'MK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Madagascar',
|
||||||
|
value: 'MG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Malawi',
|
||||||
|
value: 'MW',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Malaysia',
|
||||||
|
value: 'MY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Maldives',
|
||||||
|
value: 'MV',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Mali',
|
||||||
|
value: 'ML',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Malta',
|
||||||
|
value: 'MT',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Marshall Islands',
|
||||||
|
value: 'MH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Martinique',
|
||||||
|
value: 'MQ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Mauritania',
|
||||||
|
value: 'MR',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Mauritius',
|
||||||
|
value: 'MU',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Mayotte',
|
||||||
|
value: 'YT',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Mexico',
|
||||||
|
value: 'MX',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Micronesia, Federated States of',
|
||||||
|
value: 'FM',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Moldova, Republic of',
|
||||||
|
value: 'MD',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Monaco',
|
||||||
|
value: 'MC',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Mongolia',
|
||||||
|
value: 'MN',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Montenegro',
|
||||||
|
value: 'ME',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Montserrat',
|
||||||
|
value: 'MS',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Morocco',
|
||||||
|
value: 'MA',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Mozambique',
|
||||||
|
value: 'MZ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Myanmar',
|
||||||
|
value: 'MM',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Namibia',
|
||||||
|
value: 'NA',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Nauru',
|
||||||
|
value: 'NR',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Nepal',
|
||||||
|
value: 'NP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Netherlands',
|
||||||
|
value: 'NL',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Netherlands Antilles',
|
||||||
|
value: 'AN',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'New Caledonia',
|
||||||
|
value: 'NC',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'New Zealand',
|
||||||
|
value: 'NZ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Nicaragua',
|
||||||
|
value: 'NI',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Niger',
|
||||||
|
value: 'NE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Nigeria',
|
||||||
|
value: 'NG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Niue',
|
||||||
|
value: 'NU',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Norfolk Island',
|
||||||
|
value: 'NF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Northern Mariana Islands',
|
||||||
|
value: 'MP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Norway',
|
||||||
|
value: 'NO',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Oman',
|
||||||
|
value: 'OM',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Pakistan',
|
||||||
|
value: 'PK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Palau',
|
||||||
|
value: 'PW',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Palestinian Territory, Occupied',
|
||||||
|
value: 'PS',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Panama',
|
||||||
|
value: 'PA',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Papua New Guinea',
|
||||||
|
value: 'PG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Paraguay',
|
||||||
|
value: 'PY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Peru',
|
||||||
|
value: 'PE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Philippines',
|
||||||
|
value: 'PH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Pitcairn',
|
||||||
|
value: 'PN',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Poland',
|
||||||
|
value: 'PL',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Portugal',
|
||||||
|
value: 'PT',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Puerto Rico',
|
||||||
|
value: 'PR',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Qatar',
|
||||||
|
value: 'QA',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Reunion',
|
||||||
|
value: 'RE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Romania',
|
||||||
|
value: 'RO',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Russian Federation',
|
||||||
|
value: 'RU',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Rwanda',
|
||||||
|
value: 'RW',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Saint Helena',
|
||||||
|
value: 'SH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Saint Kitts and Nevis',
|
||||||
|
value: 'KN',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Saint Lucia',
|
||||||
|
value: 'LC',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Saint Pierre and Miquelon',
|
||||||
|
value: 'PM',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Saint Vincent and the Grenadines',
|
||||||
|
value: 'VC',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Samoa',
|
||||||
|
value: 'WS',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'San Marino',
|
||||||
|
value: 'SM',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Sao Tome and Principe',
|
||||||
|
value: 'ST',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Saudi Arabia',
|
||||||
|
value: 'SA',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Senegal',
|
||||||
|
value: 'SN',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Serbia',
|
||||||
|
value: 'RS',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Seychelles',
|
||||||
|
value: 'SC',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Sierra Leone',
|
||||||
|
value: 'SL',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Singapore',
|
||||||
|
value: 'SG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Slovakia',
|
||||||
|
value: 'SK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Slovenia',
|
||||||
|
value: 'SI',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Solomon Islands',
|
||||||
|
value: 'SB',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Somalia',
|
||||||
|
value: 'SO',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'South Africa',
|
||||||
|
value: 'ZA',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'South Georgia and the South Sandwich Islands',
|
||||||
|
value: 'GS',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Spain',
|
||||||
|
value: 'ES',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Sri Lanka',
|
||||||
|
value: 'LK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Sudan',
|
||||||
|
value: 'SD',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Suriname',
|
||||||
|
value: 'SR',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Svalbard and Jan Mayen',
|
||||||
|
value: 'SJ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Swaziland',
|
||||||
|
value: 'SZ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Sweden',
|
||||||
|
value: 'SE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Switzerland',
|
||||||
|
value: 'CH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Syrian Arab Republic',
|
||||||
|
value: 'SY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Taiwan',
|
||||||
|
value: 'TW',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Tajikistan',
|
||||||
|
value: 'TJ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Tanzania, United Republic of',
|
||||||
|
value: 'TZ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Thailand',
|
||||||
|
value: 'TH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Timor-Leste',
|
||||||
|
value: 'TL',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Togo',
|
||||||
|
value: 'TG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Tokelau',
|
||||||
|
value: 'TK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Tonga',
|
||||||
|
value: 'TO',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Trinidad and Tobago',
|
||||||
|
value: 'TT',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Tunisia',
|
||||||
|
value: 'TN',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Turkey',
|
||||||
|
value: 'TR',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Turkmenistan',
|
||||||
|
value: 'TM',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Turks and Caicos Islands',
|
||||||
|
value: 'TC',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Tuvalu',
|
||||||
|
value: 'TV',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Uganda',
|
||||||
|
value: 'UG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Ukraine',
|
||||||
|
value: 'UA',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'United Arab Emirates',
|
||||||
|
value: 'AE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'United Kingdom',
|
||||||
|
value: 'GB',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'United States',
|
||||||
|
value: 'US',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'United States Minor Outlying Islands',
|
||||||
|
value: 'UM',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Uruguay',
|
||||||
|
value: 'UY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Uzbekistan',
|
||||||
|
value: 'UZ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Vanuatu',
|
||||||
|
value: 'VU',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Venezuela',
|
||||||
|
value: 'VE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Viet Nam',
|
||||||
|
value: 'VN',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Virgin Islands, British',
|
||||||
|
value: 'VG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Virgin Islands, U.S.',
|
||||||
|
value: 'VI',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Wallis and Futuna',
|
||||||
|
value: 'WF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Western Sahara',
|
||||||
|
value: 'EH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Yemen',
|
||||||
|
value: 'YE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Zambia',
|
||||||
|
value: 'ZM',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Zimbabwe',
|
||||||
|
value: 'ZW',
|
||||||
|
},
|
||||||
|
]
|
||||||
38
src/blocks/Form/Email/index.tsx
Normal file
38
src/blocks/Form/Email/index.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import type { EmailField } from '@payloadcms/plugin-form-builder/types'
|
||||||
|
import type { FieldErrorsImpl, FieldValues, UseFormRegister } from 'react-hook-form'
|
||||||
|
|
||||||
|
import { Input } from '@/components/ui/input'
|
||||||
|
import { Label } from '@/components/ui/label'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import { Error } from '../Error'
|
||||||
|
import { Width } from '../Width'
|
||||||
|
|
||||||
|
export const Email: React.FC<
|
||||||
|
EmailField & {
|
||||||
|
errors: Partial<FieldErrorsImpl>
|
||||||
|
register: UseFormRegister<FieldValues>
|
||||||
|
}
|
||||||
|
> = ({ name, defaultValue, errors, label, register, required, width }) => {
|
||||||
|
return (
|
||||||
|
<Width width={width}>
|
||||||
|
<Label htmlFor={name}>
|
||||||
|
{label}
|
||||||
|
|
||||||
|
{required && (
|
||||||
|
<span className="required">
|
||||||
|
* <span className="sr-only">(required)</span>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</Label>
|
||||||
|
<Input
|
||||||
|
defaultValue={defaultValue}
|
||||||
|
id={name}
|
||||||
|
type="text"
|
||||||
|
{...register(name, { pattern: /^\S[^\s@]*@\S+$/, required })}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{errors[name] && <Error name={name} />}
|
||||||
|
</Width>
|
||||||
|
)
|
||||||
|
}
|
||||||
15
src/blocks/Form/Error/index.tsx
Normal file
15
src/blocks/Form/Error/index.tsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import * as React from 'react'
|
||||||
|
import { useFormContext } from 'react-hook-form'
|
||||||
|
|
||||||
|
export const Error = ({ name }: { name: string }) => {
|
||||||
|
const {
|
||||||
|
formState: { errors },
|
||||||
|
} = useFormContext()
|
||||||
|
return (
|
||||||
|
<div className="mt-2 text-red-500 text-sm">
|
||||||
|
{(errors[name]?.message as string) || 'This field is required'}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
13
src/blocks/Form/Message/index.tsx
Normal file
13
src/blocks/Form/Message/index.tsx
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import RichText from '@/components/RichText'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import { Width } from '../Width'
|
||||||
|
import { SerializedEditorState } from '@payloadcms/richtext-lexical/lexical'
|
||||||
|
|
||||||
|
export const Message: React.FC<{ message: SerializedEditorState }> = ({ message }) => {
|
||||||
|
return (
|
||||||
|
<Width className="my-12" width="100">
|
||||||
|
{message && <RichText data={message} />}
|
||||||
|
</Width>
|
||||||
|
)
|
||||||
|
}
|
||||||
36
src/blocks/Form/Number/index.tsx
Normal file
36
src/blocks/Form/Number/index.tsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import type { TextField } from '@payloadcms/plugin-form-builder/types'
|
||||||
|
import type { FieldErrorsImpl, FieldValues, UseFormRegister } from 'react-hook-form'
|
||||||
|
|
||||||
|
import { Input } from '@/components/ui/input'
|
||||||
|
import { Label } from '@/components/ui/label'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import { Error } from '../Error'
|
||||||
|
import { Width } from '../Width'
|
||||||
|
export const Number: React.FC<
|
||||||
|
TextField & {
|
||||||
|
errors: Partial<FieldErrorsImpl>
|
||||||
|
register: UseFormRegister<FieldValues>
|
||||||
|
}
|
||||||
|
> = ({ name, defaultValue, errors, label, register, required, width }) => {
|
||||||
|
return (
|
||||||
|
<Width width={width}>
|
||||||
|
<Label htmlFor={name}>
|
||||||
|
{label}
|
||||||
|
|
||||||
|
{required && (
|
||||||
|
<span className="required">
|
||||||
|
* <span className="sr-only">(required)</span>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</Label>
|
||||||
|
<Input
|
||||||
|
defaultValue={defaultValue}
|
||||||
|
id={name}
|
||||||
|
type="number"
|
||||||
|
{...register(name, { required })}
|
||||||
|
/>
|
||||||
|
{errors[name] && <Error name={name} />}
|
||||||
|
</Width>
|
||||||
|
)
|
||||||
|
}
|
||||||
63
src/blocks/Form/Select/index.tsx
Normal file
63
src/blocks/Form/Select/index.tsx
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import type { SelectField } from '@payloadcms/plugin-form-builder/types'
|
||||||
|
import type { Control, FieldErrorsImpl } from 'react-hook-form'
|
||||||
|
|
||||||
|
import { Label } from '@/components/ui/label'
|
||||||
|
import {
|
||||||
|
Select as SelectComponent,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from '@/components/ui/select'
|
||||||
|
import React from 'react'
|
||||||
|
import { Controller } from 'react-hook-form'
|
||||||
|
|
||||||
|
import { Error } from '../Error'
|
||||||
|
import { Width } from '../Width'
|
||||||
|
|
||||||
|
export const Select: React.FC<
|
||||||
|
SelectField & {
|
||||||
|
control: Control
|
||||||
|
errors: Partial<FieldErrorsImpl>
|
||||||
|
}
|
||||||
|
> = ({ name, control, errors, label, options, required, width, defaultValue }) => {
|
||||||
|
return (
|
||||||
|
<Width width={width}>
|
||||||
|
<Label htmlFor={name}>
|
||||||
|
{label}
|
||||||
|
{required && (
|
||||||
|
<span className="required">
|
||||||
|
* <span className="sr-only">(required)</span>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</Label>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
defaultValue={defaultValue}
|
||||||
|
name={name}
|
||||||
|
render={({ field: { onChange, value } }) => {
|
||||||
|
const controlledValue = options.find((t) => t.value === value)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SelectComponent onValueChange={(val) => onChange(val)} value={controlledValue?.value}>
|
||||||
|
<SelectTrigger className="w-full" id={name}>
|
||||||
|
<SelectValue placeholder={label} />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
{options.map(({ label, value }) => {
|
||||||
|
return (
|
||||||
|
<SelectItem key={value} value={value}>
|
||||||
|
{label}
|
||||||
|
</SelectItem>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</SelectContent>
|
||||||
|
</SelectComponent>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
rules={{ required }}
|
||||||
|
/>
|
||||||
|
{errors[name] && <Error name={name} />}
|
||||||
|
</Width>
|
||||||
|
)
|
||||||
|
}
|
||||||
64
src/blocks/Form/State/index.tsx
Normal file
64
src/blocks/Form/State/index.tsx
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import type { StateField } from '@payloadcms/plugin-form-builder/types'
|
||||||
|
import type { Control, FieldErrorsImpl } from 'react-hook-form'
|
||||||
|
|
||||||
|
import { Label } from '@/components/ui/label'
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from '@/components/ui/select'
|
||||||
|
import React from 'react'
|
||||||
|
import { Controller } from 'react-hook-form'
|
||||||
|
|
||||||
|
import { Error } from '../Error'
|
||||||
|
import { Width } from '../Width'
|
||||||
|
import { stateOptions } from './options'
|
||||||
|
|
||||||
|
export const State: React.FC<
|
||||||
|
StateField & {
|
||||||
|
control: Control
|
||||||
|
errors: Partial<FieldErrorsImpl>
|
||||||
|
}
|
||||||
|
> = ({ name, control, errors, label, required, width }) => {
|
||||||
|
return (
|
||||||
|
<Width width={width}>
|
||||||
|
<Label htmlFor={name}>
|
||||||
|
{label}
|
||||||
|
{required && (
|
||||||
|
<span className="required">
|
||||||
|
* <span className="sr-only">(required)</span>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</Label>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
defaultValue=""
|
||||||
|
name={name}
|
||||||
|
render={({ field: { onChange, value } }) => {
|
||||||
|
const controlledValue = stateOptions.find((t) => t.value === value)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Select onValueChange={(val) => onChange(val)} value={controlledValue?.value}>
|
||||||
|
<SelectTrigger className="w-full" id={name}>
|
||||||
|
<SelectValue placeholder={label} />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
{stateOptions.map(({ label, value }) => {
|
||||||
|
return (
|
||||||
|
<SelectItem key={value} value={value}>
|
||||||
|
{label}
|
||||||
|
</SelectItem>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
rules={{ required }}
|
||||||
|
/>
|
||||||
|
{errors[name] && <Error name={name} />}
|
||||||
|
</Width>
|
||||||
|
)
|
||||||
|
}
|
||||||
52
src/blocks/Form/State/options.ts
Normal file
52
src/blocks/Form/State/options.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
export const stateOptions = [
|
||||||
|
{ label: 'Alabama', value: 'AL' },
|
||||||
|
{ label: 'Alaska', value: 'AK' },
|
||||||
|
{ label: 'Arizona', value: 'AZ' },
|
||||||
|
{ label: 'Arkansas', value: 'AR' },
|
||||||
|
{ label: 'California', value: 'CA' },
|
||||||
|
{ label: 'Colorado', value: 'CO' },
|
||||||
|
{ label: 'Connecticut', value: 'CT' },
|
||||||
|
{ label: 'Delaware', value: 'DE' },
|
||||||
|
{ label: 'Florida', value: 'FL' },
|
||||||
|
{ label: 'Georgia', value: 'GA' },
|
||||||
|
{ label: 'Hawaii', value: 'HI' },
|
||||||
|
{ label: 'Idaho', value: 'ID' },
|
||||||
|
{ label: 'Illinois', value: 'IL' },
|
||||||
|
{ label: 'Indiana', value: 'IN' },
|
||||||
|
{ label: 'Iowa', value: 'IA' },
|
||||||
|
{ label: 'Kansas', value: 'KS' },
|
||||||
|
{ label: 'Kentucky', value: 'KY' },
|
||||||
|
{ label: 'Louisiana', value: 'LA' },
|
||||||
|
{ label: 'Maine', value: 'ME' },
|
||||||
|
{ label: 'Maryland', value: 'MD' },
|
||||||
|
{ label: 'Massachusetts', value: 'MA' },
|
||||||
|
{ label: 'Michigan', value: 'MI' },
|
||||||
|
{ label: 'Minnesota', value: 'MN' },
|
||||||
|
{ label: 'Mississippi', value: 'MS' },
|
||||||
|
{ label: 'Missouri', value: 'MO' },
|
||||||
|
{ label: 'Montana', value: 'MT' },
|
||||||
|
{ label: 'Nebraska', value: 'NE' },
|
||||||
|
{ label: 'Nevada', value: 'NV' },
|
||||||
|
{ label: 'New Hampshire', value: 'NH' },
|
||||||
|
{ label: 'New Jersey', value: 'NJ' },
|
||||||
|
{ label: 'New Mexico', value: 'NM' },
|
||||||
|
{ label: 'New York', value: 'NY' },
|
||||||
|
{ label: 'North Carolina', value: 'NC' },
|
||||||
|
{ label: 'North Dakota', value: 'ND' },
|
||||||
|
{ label: 'Ohio', value: 'OH' },
|
||||||
|
{ label: 'Oklahoma', value: 'OK' },
|
||||||
|
{ label: 'Oregon', value: 'OR' },
|
||||||
|
{ label: 'Pennsylvania', value: 'PA' },
|
||||||
|
{ label: 'Rhode Island', value: 'RI' },
|
||||||
|
{ label: 'South Carolina', value: 'SC' },
|
||||||
|
{ label: 'South Dakota', value: 'SD' },
|
||||||
|
{ label: 'Tennessee', value: 'TN' },
|
||||||
|
{ label: 'Texas', value: 'TX' },
|
||||||
|
{ label: 'Utah', value: 'UT' },
|
||||||
|
{ label: 'Vermont', value: 'VT' },
|
||||||
|
{ label: 'Virginia', value: 'VA' },
|
||||||
|
{ label: 'Washington', value: 'WA' },
|
||||||
|
{ label: 'West Virginia', value: 'WV' },
|
||||||
|
{ label: 'Wisconsin', value: 'WI' },
|
||||||
|
{ label: 'Wyoming', value: 'WY' },
|
||||||
|
]
|
||||||
32
src/blocks/Form/Text/index.tsx
Normal file
32
src/blocks/Form/Text/index.tsx
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import type { TextField } from '@payloadcms/plugin-form-builder/types'
|
||||||
|
import type { FieldErrorsImpl, FieldValues, UseFormRegister } from 'react-hook-form'
|
||||||
|
|
||||||
|
import { Input } from '@/components/ui/input'
|
||||||
|
import { Label } from '@/components/ui/label'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import { Error } from '../Error'
|
||||||
|
import { Width } from '../Width'
|
||||||
|
|
||||||
|
export const Text: React.FC<
|
||||||
|
TextField & {
|
||||||
|
errors: Partial<FieldErrorsImpl>
|
||||||
|
register: UseFormRegister<FieldValues>
|
||||||
|
}
|
||||||
|
> = ({ name, defaultValue, errors, label, register, required, width }) => {
|
||||||
|
return (
|
||||||
|
<Width width={width}>
|
||||||
|
<Label htmlFor={name}>
|
||||||
|
{label}
|
||||||
|
|
||||||
|
{required && (
|
||||||
|
<span className="required">
|
||||||
|
* <span className="sr-only">(required)</span>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</Label>
|
||||||
|
<Input defaultValue={defaultValue} id={name} type="text" {...register(name, { required })} />
|
||||||
|
{errors[name] && <Error name={name} />}
|
||||||
|
</Width>
|
||||||
|
)
|
||||||
|
}
|
||||||
40
src/blocks/Form/Textarea/index.tsx
Normal file
40
src/blocks/Form/Textarea/index.tsx
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import type { TextField } from '@payloadcms/plugin-form-builder/types'
|
||||||
|
import type { FieldErrorsImpl, FieldValues, UseFormRegister } from 'react-hook-form'
|
||||||
|
|
||||||
|
import { Label } from '@/components/ui/label'
|
||||||
|
import { Textarea as TextAreaComponent } from '@/components/ui/textarea'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import { Error } from '../Error'
|
||||||
|
import { Width } from '../Width'
|
||||||
|
|
||||||
|
export const Textarea: React.FC<
|
||||||
|
TextField & {
|
||||||
|
errors: Partial<FieldErrorsImpl>
|
||||||
|
register: UseFormRegister<FieldValues>
|
||||||
|
rows?: number
|
||||||
|
}
|
||||||
|
> = ({ name, defaultValue, errors, label, register, required, rows = 3, width }) => {
|
||||||
|
return (
|
||||||
|
<Width width={width}>
|
||||||
|
<Label htmlFor={name}>
|
||||||
|
{label}
|
||||||
|
|
||||||
|
{required && (
|
||||||
|
<span className="required">
|
||||||
|
* <span className="sr-only">(required)</span>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</Label>
|
||||||
|
|
||||||
|
<TextAreaComponent
|
||||||
|
defaultValue={defaultValue}
|
||||||
|
id={name}
|
||||||
|
rows={rows}
|
||||||
|
{...register(name, { required: required })}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{errors[name] && <Error name={name} />}
|
||||||
|
</Width>
|
||||||
|
)
|
||||||
|
}
|
||||||
13
src/blocks/Form/Width/index.tsx
Normal file
13
src/blocks/Form/Width/index.tsx
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import * as React from 'react'
|
||||||
|
|
||||||
|
export const Width: React.FC<{
|
||||||
|
children: React.ReactNode
|
||||||
|
className?: string
|
||||||
|
width?: number | string
|
||||||
|
}> = ({ children, className, width }) => {
|
||||||
|
return (
|
||||||
|
<div className={className} style={{ maxWidth: width ? `${width}%` : undefined }}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
51
src/blocks/Form/config.ts
Normal file
51
src/blocks/Form/config.ts
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import type { Block } from 'payload'
|
||||||
|
|
||||||
|
import {
|
||||||
|
FixedToolbarFeature,
|
||||||
|
HeadingFeature,
|
||||||
|
InlineToolbarFeature,
|
||||||
|
lexicalEditor,
|
||||||
|
} from '@payloadcms/richtext-lexical'
|
||||||
|
|
||||||
|
export const FormBlock: Block = {
|
||||||
|
slug: 'formBlock',
|
||||||
|
interfaceName: 'FormBlock',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'form',
|
||||||
|
type: 'relationship',
|
||||||
|
relationTo: 'forms',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'enableIntro',
|
||||||
|
type: 'checkbox',
|
||||||
|
label: 'Enable Intro Content',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'introContent',
|
||||||
|
type: 'richText',
|
||||||
|
admin: {
|
||||||
|
condition: (_, { enableIntro }) => Boolean(enableIntro),
|
||||||
|
},
|
||||||
|
editor: lexicalEditor({
|
||||||
|
features: ({ rootFeatures }) => {
|
||||||
|
return [
|
||||||
|
...rootFeatures,
|
||||||
|
HeadingFeature({ enabledHeadingSizes: ['h1', 'h2', 'h3', 'h4'] }),
|
||||||
|
FixedToolbarFeature(),
|
||||||
|
InlineToolbarFeature(),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
label: 'Intro Content',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
graphQL: {
|
||||||
|
singularName: 'FormBlock',
|
||||||
|
},
|
||||||
|
labels: {
|
||||||
|
plural: 'Form Blocks',
|
||||||
|
singular: 'Form Block',
|
||||||
|
},
|
||||||
|
}
|
||||||
21
src/blocks/Form/fields.tsx
Normal file
21
src/blocks/Form/fields.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { Checkbox } from './Checkbox'
|
||||||
|
import { Country } from './Country'
|
||||||
|
import { Email } from './Email'
|
||||||
|
import { Message } from './Message'
|
||||||
|
import { Number } from './Number'
|
||||||
|
import { Select } from './Select'
|
||||||
|
import { State } from './State'
|
||||||
|
import { Text } from './Text'
|
||||||
|
import { Textarea } from './Textarea'
|
||||||
|
|
||||||
|
export const fields = {
|
||||||
|
checkbox: Checkbox,
|
||||||
|
country: Country,
|
||||||
|
email: Email,
|
||||||
|
message: Message,
|
||||||
|
number: Number,
|
||||||
|
select: Select,
|
||||||
|
state: State,
|
||||||
|
text: Text,
|
||||||
|
textarea: Textarea,
|
||||||
|
}
|
||||||
1
src/blocks/MediaBlock/Component.tsx
Normal file
1
src/blocks/MediaBlock/Component.tsx
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
14
src/blocks/MediaBlock/config.ts
Normal file
14
src/blocks/MediaBlock/config.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import type { Block } from 'payload'
|
||||||
|
|
||||||
|
export const MediaBlock: Block = {
|
||||||
|
slug: 'mediaBlock',
|
||||||
|
interfaceName: 'MediaBlock',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'media',
|
||||||
|
type: 'upload',
|
||||||
|
relationTo: 'media',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
32
src/blocks/RelatedPosts/Component.tsx
Normal file
32
src/blocks/RelatedPosts/Component.tsx
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// import clsx from 'clsx'
|
||||||
|
// import React from 'react'
|
||||||
|
// import RichText from '@/components/RichText'
|
||||||
|
|
||||||
|
// import type { Post } from '@/payload-types'
|
||||||
|
|
||||||
|
// import { Card } from '../../components/Card'
|
||||||
|
// import { SerializedEditorState } from '@payloadcms/richtext-lexical/lexical'
|
||||||
|
|
||||||
|
// export type RelatedPostsProps = {
|
||||||
|
// className?: string
|
||||||
|
// docs?: Post[]
|
||||||
|
// introContent?: SerializedEditorState
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export const RelatedPosts: React.FC<RelatedPostsProps> = (props) => {
|
||||||
|
// const { className, docs, introContent } = props
|
||||||
|
|
||||||
|
// return (
|
||||||
|
// <div className={clsx('lg:container', className)}>
|
||||||
|
// {introContent && <RichText data={introContent} enableGutter={false} />}
|
||||||
|
|
||||||
|
// <div className="grid grid-cols-1 md:grid-cols-2 gap-4 md:gap-8 items-stretch">
|
||||||
|
// {docs?.map((doc, index) => {
|
||||||
|
// if (typeof doc === 'string') return null
|
||||||
|
|
||||||
|
// return <Card key={index} doc={doc} relationTo="posts" showCategories />
|
||||||
|
// })}
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
// )
|
||||||
|
// }
|
||||||
0
src/blocks/RenderBlocks.ts
Normal file
0
src/blocks/RenderBlocks.ts
Normal file
26
src/collections/Categories.ts
Normal file
26
src/collections/Categories.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// import type { CollectionConfig } from 'payload'
|
||||||
|
|
||||||
|
// import { anyone } from '../access/anyone'
|
||||||
|
// import { authenticated } from '../access/authenticated'
|
||||||
|
// import { slugField } from '@/fields/slug'
|
||||||
|
|
||||||
|
// export const Categories: CollectionConfig = {
|
||||||
|
// slug: 'categories',
|
||||||
|
// access: {
|
||||||
|
// create: authenticated,
|
||||||
|
// delete: authenticated,
|
||||||
|
// read: anyone,
|
||||||
|
// update: authenticated,
|
||||||
|
// },
|
||||||
|
// admin: {
|
||||||
|
// useAsTitle: 'title',
|
||||||
|
// },
|
||||||
|
// fields: [
|
||||||
|
// {
|
||||||
|
// name: 'title',
|
||||||
|
// type: 'text',
|
||||||
|
// required: true,
|
||||||
|
// },
|
||||||
|
// ...slugField(),
|
||||||
|
// ],
|
||||||
|
// }
|
||||||
16
src/collections/Media.ts
Normal file
16
src/collections/Media.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import type { CollectionConfig } from 'payload'
|
||||||
|
|
||||||
|
export const Media: CollectionConfig = {
|
||||||
|
slug: 'media',
|
||||||
|
access: {
|
||||||
|
read: () => true,
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'alt',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
upload: true,
|
||||||
|
}
|
||||||
0
src/collections/Pages/hooks/revalidatePage.ts
Normal file
0
src/collections/Pages/hooks/revalidatePage.ts
Normal file
0
src/collections/Pages/indext.ts
Normal file
0
src/collections/Pages/indext.ts
Normal file
13
src/collections/Users.ts
Normal file
13
src/collections/Users.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import type { CollectionConfig } from 'payload'
|
||||||
|
|
||||||
|
export const Users: CollectionConfig = {
|
||||||
|
slug: 'users',
|
||||||
|
admin: {
|
||||||
|
useAsTitle: 'email',
|
||||||
|
},
|
||||||
|
auth: true,
|
||||||
|
fields: [
|
||||||
|
// Email added by default
|
||||||
|
// Add more fields as needed
|
||||||
|
],
|
||||||
|
}
|
||||||
0
src/collections/posts/hooks/populateAuthors.ts
Normal file
0
src/collections/posts/hooks/populateAuthors.ts
Normal file
0
src/collections/posts/hooks/revalidatePost.ts
Normal file
0
src/collections/posts/hooks/revalidatePost.ts
Normal file
0
src/collections/posts/index.ts
Normal file
0
src/collections/posts/index.ts
Normal file
@ -1,26 +1,57 @@
|
|||||||
import Link from 'next/link';
|
// import Link from 'next/link';
|
||||||
import breadCrumbBg from "../../../public/assets/img/pages/page-banner.jpg";
|
// import breadCrumbBg from "../../../public/assets/img/pages/page-banner.jpg";
|
||||||
|
|
||||||
const BreadCrumb = ({title, innerTitle}) => {
|
// const BreadCrumb = ({title, innerTitle}) => {
|
||||||
const firstThreeWords = title?.split(' ').slice(0, 1);
|
// const firstThreeWords = title?.split(' ').slice(0, 1);
|
||||||
return (
|
// return (
|
||||||
<div className="page__banner" style={{backgroundImage: `url(${breadCrumbBg.src})`}}>
|
// <div className="page__banner" style={{backgroundImage: `url(${breadCrumbBg.src})`}}>
|
||||||
<div className="container">
|
// <div className="container">
|
||||||
<div className="row">
|
// <div className="row">
|
||||||
<div className="col-xl-12">
|
// <div className="col-xl-12">
|
||||||
<div className="page__banner-content">
|
// <div className="page__banner-content">
|
||||||
<span>{firstThreeWords}</span>
|
// <span>{firstThreeWords}</span>
|
||||||
<ul>
|
// <ul>
|
||||||
<li><Link href="/">Home</Link><span>|</span></li>
|
// <li><Link href="/">Home</Link><span>|</span></li>
|
||||||
<li>{innerTitle}</li>
|
// <li>{innerTitle}</li>
|
||||||
</ul>
|
// </ul>
|
||||||
<h1>{title}</h1>
|
// <h1>{title}</h1>
|
||||||
</div>
|
// </div>
|
||||||
</div>
|
// </div>
|
||||||
</div>
|
// </div>
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
// );
|
||||||
|
// };
|
||||||
|
|
||||||
|
// export default BreadCrumb;
|
||||||
|
|
||||||
|
|
||||||
|
const BreadCrumb = ({ title, innerTitle }) => {
|
||||||
|
const firstThreeWords = title?.split(' ').slice(0, 1);
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="page__banner"
|
||||||
|
style={{ backgroundImage: `url("/assets/img/pages/page-banner.jpg")` }}
|
||||||
|
>
|
||||||
|
<div className="container">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-xl-12">
|
||||||
|
<div className="page__banner-content">
|
||||||
|
<span>{firstThreeWords}</span>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<Link href="/">Home</Link>
|
||||||
|
<span>|</span>
|
||||||
|
</li>
|
||||||
|
<li>{innerTitle}</li>
|
||||||
|
</ul>
|
||||||
|
<h1>{title}</h1>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default BreadCrumb;
|
export default BreadCrumb;
|
||||||
|
|||||||
@ -1,25 +1,57 @@
|
|||||||
import { useState } from "react";
|
// import { useState } from "react";
|
||||||
import CountUp from 'react-countup';
|
// import CountUp from 'react-countup';
|
||||||
import ScrollTrigger from "react-scroll-trigger";
|
// import ScrollTrigger from "react-scroll-trigger";
|
||||||
import ReactSkillBar from 'react-skillbars';
|
// import ReactSkillBar from 'react-skillbars';
|
||||||
|
|
||||||
const SkillBarItem = ({countUp}) => {
|
// const SkillBarItem = ({countUp}) => {
|
||||||
const [skillBar, setSkillBar] = useState(false);
|
// const [skillBar, setSkillBar] = useState(false);
|
||||||
const skillLevel = [
|
// const skillLevel = [
|
||||||
{ type: 'one', level: countUp }
|
// { type: 'one', level: countUp }
|
||||||
];
|
// ];
|
||||||
return (
|
// return (
|
||||||
<>
|
// <>
|
||||||
<ScrollTrigger onEnter={()=> setSkillBar(true)} onExit={()=> setSkillBar(false)}>
|
// <ScrollTrigger onEnter={()=> setSkillBar(true)} onExit={()=> setSkillBar(false)}>
|
||||||
<div className="skill__area-item-inner">
|
// <div className="skill__area-item-inner">
|
||||||
{skillBar && <ReactSkillBar skills={skillLevel} height={10} animationDuration={2000} />}
|
// {skillBar && <ReactSkillBar skills={skillLevel} height={10} animationDuration={2000} />}
|
||||||
<span className="skill__area-item-count text-two">
|
// <span className="skill__area-item-count text-two">
|
||||||
<span className="counter text-two">{skillBar && <CountUp start={0} end={countUp} duration={4} delay={1}></CountUp>}</span>%
|
// <span className="counter text-two">{skillBar && <CountUp start={0} end={countUp} duration={4} delay={1}></CountUp>}</span>%
|
||||||
</span>
|
// </span>
|
||||||
</div>
|
// </div>
|
||||||
</ScrollTrigger>
|
// </ScrollTrigger>
|
||||||
</>
|
// </>
|
||||||
);
|
// );
|
||||||
|
// };
|
||||||
|
|
||||||
|
// export default SkillBarItem;
|
||||||
|
|
||||||
|
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import CountUp from "react-countup";
|
||||||
|
import { useInView } from "react-intersection-observer";
|
||||||
|
import ReactSkillBar from "react-skillbars";
|
||||||
|
|
||||||
|
const SkillBarItem = ({ countUp }) => {
|
||||||
|
const [skillBar, setSkillBar] = useState(false);
|
||||||
|
const { ref, inView } = useInView({ triggerOnce: true });
|
||||||
|
const skillLevel = [{ type: "one", level: countUp }];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (inView) setSkillBar(true);
|
||||||
|
}, [inView]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div ref={ref} className="skill__area-item-inner">
|
||||||
|
{skillBar && (
|
||||||
|
<ReactSkillBar skills={skillLevel} height={10} animationDuration={2000} />
|
||||||
|
)}
|
||||||
|
<span className="skill__area-item-count text-two">
|
||||||
|
<span className="counter text-two">
|
||||||
|
{skillBar && <CountUp start={0} end={countUp} duration={4} delay={1} />}
|
||||||
|
</span>
|
||||||
|
%
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SkillBarItem;
|
export default SkillBarItem;
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import SEO from '@/src/components/data/seo';
|
import SEO from '@/components/data/seo';
|
||||||
import HeaderThree from '@/src/components/layout/header/header-three';
|
import HeaderThree from '@/components/layout/header/header-three';
|
||||||
import BreadCrumb from '../common/breadcrumb';
|
import BreadCrumb from '../common/breadcrumb';
|
||||||
import Error from './error';
|
import Error from './error';
|
||||||
import FooterThree from '@/src/components/layout/footer/footer-three';
|
import FooterThree from '@/components/layout/footer/footer-three';
|
||||||
import ScrollToTop from '../common/scroll/scroll-to-top';
|
import ScrollToTop from '../common/scroll/scroll-to-top';
|
||||||
|
|
||||||
const ErrorPage = () => {
|
const ErrorPage = () => {
|
||||||
|
|||||||
299
src/payload-types.ts
Normal file
299
src/payload-types.ts
Normal file
@ -0,0 +1,299 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* This file was automatically generated by Payload.
|
||||||
|
* DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config,
|
||||||
|
* and re-run `payload generate:types` to regenerate this file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supported timezones in IANA format.
|
||||||
|
*
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "supportedTimezones".
|
||||||
|
*/
|
||||||
|
export type SupportedTimezones =
|
||||||
|
| 'Pacific/Midway'
|
||||||
|
| 'Pacific/Niue'
|
||||||
|
| 'Pacific/Honolulu'
|
||||||
|
| 'Pacific/Rarotonga'
|
||||||
|
| 'America/Anchorage'
|
||||||
|
| 'Pacific/Gambier'
|
||||||
|
| 'America/Los_Angeles'
|
||||||
|
| 'America/Tijuana'
|
||||||
|
| 'America/Denver'
|
||||||
|
| 'America/Phoenix'
|
||||||
|
| 'America/Chicago'
|
||||||
|
| 'America/Guatemala'
|
||||||
|
| 'America/New_York'
|
||||||
|
| 'America/Bogota'
|
||||||
|
| 'America/Caracas'
|
||||||
|
| 'America/Santiago'
|
||||||
|
| 'America/Buenos_Aires'
|
||||||
|
| 'America/Sao_Paulo'
|
||||||
|
| 'Atlantic/South_Georgia'
|
||||||
|
| 'Atlantic/Azores'
|
||||||
|
| 'Atlantic/Cape_Verde'
|
||||||
|
| 'Europe/London'
|
||||||
|
| 'Europe/Berlin'
|
||||||
|
| 'Africa/Lagos'
|
||||||
|
| 'Europe/Athens'
|
||||||
|
| 'Africa/Cairo'
|
||||||
|
| 'Europe/Moscow'
|
||||||
|
| 'Asia/Riyadh'
|
||||||
|
| 'Asia/Dubai'
|
||||||
|
| 'Asia/Baku'
|
||||||
|
| 'Asia/Karachi'
|
||||||
|
| 'Asia/Tashkent'
|
||||||
|
| 'Asia/Calcutta'
|
||||||
|
| 'Asia/Dhaka'
|
||||||
|
| 'Asia/Almaty'
|
||||||
|
| 'Asia/Jakarta'
|
||||||
|
| 'Asia/Bangkok'
|
||||||
|
| 'Asia/Shanghai'
|
||||||
|
| 'Asia/Singapore'
|
||||||
|
| 'Asia/Tokyo'
|
||||||
|
| 'Asia/Seoul'
|
||||||
|
| 'Australia/Brisbane'
|
||||||
|
| 'Australia/Sydney'
|
||||||
|
| 'Pacific/Guam'
|
||||||
|
| 'Pacific/Noumea'
|
||||||
|
| 'Pacific/Auckland'
|
||||||
|
| 'Pacific/Fiji';
|
||||||
|
|
||||||
|
export interface Config {
|
||||||
|
auth: {
|
||||||
|
users: UserAuthOperations;
|
||||||
|
};
|
||||||
|
blocks: {};
|
||||||
|
collections: {
|
||||||
|
users: User;
|
||||||
|
media: Media;
|
||||||
|
'payload-locked-documents': PayloadLockedDocument;
|
||||||
|
'payload-preferences': PayloadPreference;
|
||||||
|
'payload-migrations': PayloadMigration;
|
||||||
|
};
|
||||||
|
collectionsJoins: {};
|
||||||
|
collectionsSelect: {
|
||||||
|
users: UsersSelect<false> | UsersSelect<true>;
|
||||||
|
media: MediaSelect<false> | MediaSelect<true>;
|
||||||
|
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
||||||
|
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
|
||||||
|
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
|
||||||
|
};
|
||||||
|
db: {
|
||||||
|
defaultIDType: string;
|
||||||
|
};
|
||||||
|
globals: {};
|
||||||
|
globalsSelect: {};
|
||||||
|
locale: null;
|
||||||
|
user: User & {
|
||||||
|
collection: 'users';
|
||||||
|
};
|
||||||
|
jobs: {
|
||||||
|
tasks: unknown;
|
||||||
|
workflows: unknown;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
export interface UserAuthOperations {
|
||||||
|
forgotPassword: {
|
||||||
|
email: string;
|
||||||
|
password: string;
|
||||||
|
};
|
||||||
|
login: {
|
||||||
|
email: string;
|
||||||
|
password: string;
|
||||||
|
};
|
||||||
|
registerFirstUser: {
|
||||||
|
email: string;
|
||||||
|
password: string;
|
||||||
|
};
|
||||||
|
unlock: {
|
||||||
|
email: string;
|
||||||
|
password: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "users".
|
||||||
|
*/
|
||||||
|
export interface User {
|
||||||
|
id: string;
|
||||||
|
updatedAt: string;
|
||||||
|
createdAt: string;
|
||||||
|
email: string;
|
||||||
|
resetPasswordToken?: string | null;
|
||||||
|
resetPasswordExpiration?: string | null;
|
||||||
|
salt?: string | null;
|
||||||
|
hash?: string | null;
|
||||||
|
loginAttempts?: number | null;
|
||||||
|
lockUntil?: string | null;
|
||||||
|
sessions?:
|
||||||
|
| {
|
||||||
|
id: string;
|
||||||
|
createdAt?: string | null;
|
||||||
|
expiresAt: string;
|
||||||
|
}[]
|
||||||
|
| null;
|
||||||
|
password?: string | null;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "media".
|
||||||
|
*/
|
||||||
|
export interface Media {
|
||||||
|
id: string;
|
||||||
|
alt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
createdAt: string;
|
||||||
|
url?: string | null;
|
||||||
|
thumbnailURL?: string | null;
|
||||||
|
filename?: string | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
focalX?: number | null;
|
||||||
|
focalY?: number | null;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "payload-locked-documents".
|
||||||
|
*/
|
||||||
|
export interface PayloadLockedDocument {
|
||||||
|
id: string;
|
||||||
|
document?:
|
||||||
|
| ({
|
||||||
|
relationTo: 'users';
|
||||||
|
value: string | User;
|
||||||
|
} | null)
|
||||||
|
| ({
|
||||||
|
relationTo: 'media';
|
||||||
|
value: string | Media;
|
||||||
|
} | null);
|
||||||
|
globalSlug?: string | null;
|
||||||
|
user: {
|
||||||
|
relationTo: 'users';
|
||||||
|
value: string | User;
|
||||||
|
};
|
||||||
|
updatedAt: string;
|
||||||
|
createdAt: string;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "payload-preferences".
|
||||||
|
*/
|
||||||
|
export interface PayloadPreference {
|
||||||
|
id: string;
|
||||||
|
user: {
|
||||||
|
relationTo: 'users';
|
||||||
|
value: string | User;
|
||||||
|
};
|
||||||
|
key?: string | null;
|
||||||
|
value?:
|
||||||
|
| {
|
||||||
|
[k: string]: unknown;
|
||||||
|
}
|
||||||
|
| unknown[]
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| boolean
|
||||||
|
| null;
|
||||||
|
updatedAt: string;
|
||||||
|
createdAt: string;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "payload-migrations".
|
||||||
|
*/
|
||||||
|
export interface PayloadMigration {
|
||||||
|
id: string;
|
||||||
|
name?: string | null;
|
||||||
|
batch?: number | null;
|
||||||
|
updatedAt: string;
|
||||||
|
createdAt: string;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "users_select".
|
||||||
|
*/
|
||||||
|
export interface UsersSelect<T extends boolean = true> {
|
||||||
|
updatedAt?: T;
|
||||||
|
createdAt?: T;
|
||||||
|
email?: T;
|
||||||
|
resetPasswordToken?: T;
|
||||||
|
resetPasswordExpiration?: T;
|
||||||
|
salt?: T;
|
||||||
|
hash?: T;
|
||||||
|
loginAttempts?: T;
|
||||||
|
lockUntil?: T;
|
||||||
|
sessions?:
|
||||||
|
| T
|
||||||
|
| {
|
||||||
|
id?: T;
|
||||||
|
createdAt?: T;
|
||||||
|
expiresAt?: T;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "media_select".
|
||||||
|
*/
|
||||||
|
export interface MediaSelect<T extends boolean = true> {
|
||||||
|
alt?: T;
|
||||||
|
updatedAt?: T;
|
||||||
|
createdAt?: T;
|
||||||
|
url?: T;
|
||||||
|
thumbnailURL?: T;
|
||||||
|
filename?: T;
|
||||||
|
mimeType?: T;
|
||||||
|
filesize?: T;
|
||||||
|
width?: T;
|
||||||
|
height?: T;
|
||||||
|
focalX?: T;
|
||||||
|
focalY?: T;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "payload-locked-documents_select".
|
||||||
|
*/
|
||||||
|
export interface PayloadLockedDocumentsSelect<T extends boolean = true> {
|
||||||
|
document?: T;
|
||||||
|
globalSlug?: T;
|
||||||
|
user?: T;
|
||||||
|
updatedAt?: T;
|
||||||
|
createdAt?: T;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "payload-preferences_select".
|
||||||
|
*/
|
||||||
|
export interface PayloadPreferencesSelect<T extends boolean = true> {
|
||||||
|
user?: T;
|
||||||
|
key?: T;
|
||||||
|
value?: T;
|
||||||
|
updatedAt?: T;
|
||||||
|
createdAt?: T;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "payload-migrations_select".
|
||||||
|
*/
|
||||||
|
export interface PayloadMigrationsSelect<T extends boolean = true> {
|
||||||
|
name?: T;
|
||||||
|
batch?: T;
|
||||||
|
updatedAt?: T;
|
||||||
|
createdAt?: T;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "auth".
|
||||||
|
*/
|
||||||
|
export interface Auth {
|
||||||
|
[k: string]: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module 'payload' {
|
||||||
|
export interface GeneratedTypes extends Config {}
|
||||||
|
}
|
||||||
1778
src/payload.config.ts
Normal file
1778
src/payload.config.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,75 +0,0 @@
|
|||||||
// {
|
|
||||||
// "compilerOptions": {
|
|
||||||
// "lib": [
|
|
||||||
// "dom",
|
|
||||||
// "dom.iterable",
|
|
||||||
// "esnext"
|
|
||||||
// ],
|
|
||||||
// "allowJs": true,
|
|
||||||
// "skipLibCheck": true,
|
|
||||||
// "strict": false,
|
|
||||||
// "noEmit": true,
|
|
||||||
// "incremental": true,
|
|
||||||
// "esModuleInterop": true,
|
|
||||||
// "module": "esnext",
|
|
||||||
// "moduleResolution": "node",
|
|
||||||
// "resolveJsonModule": true,
|
|
||||||
// "isolatedModules": true,
|
|
||||||
// "jsx": "preserve",
|
|
||||||
// "plugins": [
|
|
||||||
// {
|
|
||||||
// "name": "next"
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
// },
|
|
||||||
// "include": [
|
|
||||||
// "next-env.d.ts",
|
|
||||||
// ".next/types/**/*.ts",
|
|
||||||
// "**/*.ts",
|
|
||||||
// "**/*.tsx"
|
|
||||||
// ],
|
|
||||||
// "exclude": [
|
|
||||||
// "node_modules"
|
|
||||||
// ]
|
|
||||||
// }
|
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"baseUrl": ".",
|
|
||||||
"paths": {
|
|
||||||
"@/*": [
|
|
||||||
"src/*"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"lib": [
|
|
||||||
"dom",
|
|
||||||
"dom.iterable",
|
|
||||||
"esnext"
|
|
||||||
],
|
|
||||||
"allowJs": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"strict": false,
|
|
||||||
"noEmit": true,
|
|
||||||
"incremental": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"module": "esnext",
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"resolveJsonModule": true,
|
|
||||||
"isolatedModules": true,
|
|
||||||
"jsx": "preserve",
|
|
||||||
"plugins": [
|
|
||||||
{
|
|
||||||
"name": "next"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"target": "ES2017"
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"next-env.d.ts",
|
|
||||||
".next/types/**/*.ts",
|
|
||||||
"**/*.ts",
|
|
||||||
"**/*.tsx"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"node_modules"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user