refactor: migrate to pnpm monorepo with Payload CMS backend and Astro frontend to support scalable website development and AI-assisted workflows
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
.seedButton {
|
||||
appearance: none;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
text-decoration: underline;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
opacity: 0.85;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
'use client'
|
||||
|
||||
import React, { Fragment, useCallback, useState } from 'react'
|
||||
import { toast } from '@payloadcms/ui'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
const SuccessMessage: React.FC = () => (
|
||||
<div>
|
||||
Database seeded! You can now{' '}
|
||||
<a target="_blank" href="/">
|
||||
visit your website
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
|
||||
export const SeedButton: React.FC = () => {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [seeded, setSeeded] = useState(false)
|
||||
const [error, setError] = useState<null | string>(null)
|
||||
|
||||
const handleClick = useCallback(
|
||||
async (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
e.preventDefault()
|
||||
|
||||
if (seeded) {
|
||||
toast.info('Database already seeded.')
|
||||
return
|
||||
}
|
||||
if (loading) {
|
||||
toast.info('Seeding already in progress.')
|
||||
return
|
||||
}
|
||||
if (error) {
|
||||
toast.error(`An error occurred, please refresh and try again.`)
|
||||
return
|
||||
}
|
||||
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
toast.promise(
|
||||
new Promise((resolve, reject) => {
|
||||
try {
|
||||
fetch('/next/seed', { method: 'POST', credentials: 'include' })
|
||||
.then((res) => {
|
||||
if (res.ok) {
|
||||
resolve(true)
|
||||
setSeeded(true)
|
||||
} else {
|
||||
reject('An error occurred while seeding.')
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error)
|
||||
})
|
||||
} catch (error) {
|
||||
reject(error)
|
||||
}
|
||||
}),
|
||||
{
|
||||
loading: 'Seeding with data....',
|
||||
success: <SuccessMessage />,
|
||||
error: 'An error occurred while seeding.',
|
||||
},
|
||||
)
|
||||
} catch (err) {
|
||||
const error = err instanceof Error ? err.message : String(err)
|
||||
setError(error)
|
||||
}
|
||||
},
|
||||
[loading, seeded, error],
|
||||
)
|
||||
|
||||
let message = ''
|
||||
if (loading) message = ' (seeding...)'
|
||||
if (seeded) message = ' (done!)'
|
||||
if (error) message = ` (error: ${error})`
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<button className="seedButton" onClick={handleClick}>
|
||||
Seed your database
|
||||
</button>
|
||||
{message}
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
24
apps/backend/src/components/BeforeDashboard/index.scss
Normal file
24
apps/backend/src/components/BeforeDashboard/index.scss
Normal file
@@ -0,0 +1,24 @@
|
||||
@import '~@payloadcms/ui/scss';
|
||||
|
||||
.dashboard .before-dashboard {
|
||||
margin-bottom: base(1.5);
|
||||
|
||||
&__banner {
|
||||
& h4 {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__instructions {
|
||||
list-style: decimal;
|
||||
margin-bottom: base(0.5);
|
||||
|
||||
& li {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
& a:hover {
|
||||
opacity: 0.85;
|
||||
}
|
||||
}
|
||||
74
apps/backend/src/components/BeforeDashboard/index.tsx
Normal file
74
apps/backend/src/components/BeforeDashboard/index.tsx
Normal file
@@ -0,0 +1,74 @@
|
||||
import { Banner } from '@payloadcms/ui/elements/Banner'
|
||||
import React from 'react'
|
||||
|
||||
import { SeedButton } from './SeedButton'
|
||||
import './index.scss'
|
||||
|
||||
const baseClass = 'before-dashboard'
|
||||
|
||||
const BeforeDashboard: React.FC = () => {
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
<Banner className={`${baseClass}__banner`} type="success">
|
||||
<h4>Welcome to your dashboard!</h4>
|
||||
</Banner>
|
||||
Here's what to do next:
|
||||
<ul className={`${baseClass}__instructions`}>
|
||||
<li>
|
||||
<SeedButton />
|
||||
{' with a few pages, posts, and projects to jump-start your new site, then '}
|
||||
<a href="/" target="_blank">
|
||||
visit your website
|
||||
</a>
|
||||
{' to see the results.'}
|
||||
</li>
|
||||
<li>
|
||||
If you created this repo using Payload Cloud, head over to GitHub and clone it to your
|
||||
local machine. It will be under the <i>GitHub Scope</i> that you selected when creating
|
||||
this project.
|
||||
</li>
|
||||
<li>
|
||||
{'Modify your '}
|
||||
<a
|
||||
href="https://payloadcms.com/docs/configuration/collections"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
collections
|
||||
</a>
|
||||
{' and add more '}
|
||||
<a
|
||||
href="https://payloadcms.com/docs/fields/overview"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
fields
|
||||
</a>
|
||||
{' as needed. If you are new to Payload, we also recommend you check out the '}
|
||||
<a
|
||||
href="https://payloadcms.com/docs/getting-started/what-is-payload"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
Getting Started
|
||||
</a>
|
||||
{' docs.'}
|
||||
</li>
|
||||
<li>
|
||||
Commit and push your changes to the repository to trigger a redeployment of your project.
|
||||
</li>
|
||||
</ul>
|
||||
{'Pro Tip: This block is a '}
|
||||
<a
|
||||
href="https://payloadcms.com/docs/custom-components/overview"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
custom component
|
||||
</a>
|
||||
, you can remove it at any time by updating your <strong>payload.config</strong>.
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default BeforeDashboard
|
||||
Reference in New Issue
Block a user