Skip to content

Instantly share code, notes, and snippets.

@sramam
Last active February 20, 2025 04:00
Show Gist options
  • Save sramam/9606bf02270d51900fbd3690d183c3fd to your computer and use it in GitHub Desktop.
Save sramam/9606bf02270d51900fbd3690d183c3fd to your computer and use it in GitHub Desktop.
Payload Utilities
import { getPayload } from 'payload'
// import config from '@payload-config'
import config from "../payload.config"
import 'dotenv/config'
const payload = await getPayload({ config })
payload.find({
collection: 'pages',
}).then(console.log);
pnpm i @payloadcms/db-sqlite
pnpm un @payloadcms/db-mongoose
# Switch DATABASE_URI in .env
cp .env.example .env
sed -i '' -e 's/DATABASE_URI=.*/DATABASE_URI=file:.\/db.sqlite/' .env
# switch the db adapter used in the code
sed -i '' -e 's/^import { mongooseAdapter } from .*/import { sqliteAdapter } from "@payloadcms\/db-sqlite"/' \
src/payload.config.ts
# Modify the db setup section to switch from mongooseAdapter to sqliteAdapter
sed -i '' -e '/mongooseAdapter/{
s/mongooseAdapter/sqliteAdapter/;
s/url: process.env.DATABASE_URI as string,/client: {\
url: process.env.DATABASE_URI as string,/;
}' src/payload.config.ts
# run the regeneration step
pnpm payload generate:types
pnpm run generate:importmap
pnpm payload migrate:create step_1
# if all is well, this should run without error
pnpm dev
'use client'
import React, { useState, useEffect, useRef } from 'react'
import { TextFieldClientProps } from 'payload'
import {
TextInput,
FieldLabel,
CheckboxInput,
useFormFields,
useForm,
useField,
} from '@payloadcms/ui'
// Simplified slugify function
const slugify = (val: string): string =>
(val ?? "")
.trim()
.replace(/ /g, '-')
.replace(/[^\w-]+/g, '')
.toLowerCase()
type SlugComponentProps = {
sourceField?: string
checkboxFieldPath: string
} & TextFieldClientProps
export const SlugComponent: React.FC<SlugComponentProps> = ({
field,
sourceField = 'title', // Default source field
checkboxFieldPath: checkboxFieldPathFromProps,
path,
readOnly: readOnlyFromProps,
}) => {
const { label } = field
const { value, setValue } = useField<string>({ path: path || field.name })
const { dispatchFields } = useForm()
// Ref to hold the current lock state
const lockSlugRef = useRef(false)
const [lockSlug, setLockSlug] = useState(false)
// Get the current value of the source field (e.g., title)
const sourceFieldValue = useFormFields(
([fields]) => fields[sourceField]?.value as string
)
// When the title changes, auto-update the slug if not locked
useEffect(() => {
if (!lockSlugRef.current) {
setValue(slugify(sourceFieldValue))
}
}, [sourceFieldValue, setValue])
// Handle manual slug changes
const handleSlugChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const inputVal = e.target.value
// If the field is emptied, unlock the slug and update the value
if (inputVal === "") {
lockSlugRef.current = false
setLockSlug(false)
setValue("")
} else {
const newSlug = slugify(inputVal)
// If the manual input differs from the auto-generated slug, lock it
if (newSlug !== slugify(sourceFieldValue)) {
lockSlugRef.current = true
setLockSlug(true)
} else {
// If it matches, unlock it to resume auto-updating
lockSlugRef.current = false
setLockSlug(false)
}
setValue(newSlug)
}
}
// Toggle the lockSlug state via the checkbox
const handleCheckboxToggle = () => {
lockSlugRef.current = !lockSlugRef.current
setLockSlug(lockSlugRef.current)
}
return (
<div className="field-type slug-field-component">
<div className="label-wrapper">
<FieldLabel htmlFor={`field-${path}`} label={label} />
</div>
<TextInput
value={value}
onChange={handleSlugChange}
path={path || field.name}
/>
<div style={{ display: 'flex', alignItems: 'center', marginTop: '8px', gap: '8px' }}>
<CheckboxInput
checked={lockSlug}
onToggle={handleCheckboxToggle}
/>
<FieldLabel label="Lock Slug" />
</div>
</div>
)
}
export default SlugComponent
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment