feat: Next 16 + Payload 3 scaffold with Kaniko CI and Swarm deploy (#1)
Some checks failed
ci/woodpecker/push/web Pipeline failed

Co-authored-by: Jason Woltje <jason@diversecanvas.com>
Co-committed-by: Jason Woltje <jason@diversecanvas.com>
This commit was merged in pull request #1.
This commit is contained in:
2026-04-14 03:21:17 +00:00
committed by jason.woltje
parent c800bef739
commit 8c5a25e976
51 changed files with 9353 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
import type { CollectionConfig } from "payload";
export const Categories: CollectionConfig = {
slug: "categories",
access: { read: () => true },
admin: { useAsTitle: "name", defaultColumns: ["name", "slug", "accent"] },
fields: [
{ name: "name", type: "text", required: true },
{ name: "slug", type: "text", required: true, unique: true, index: true },
{
name: "accent",
type: "select",
defaultValue: "primary",
options: [
{ label: "Primary (cyan)", value: "primary" },
{ label: "Secondary (magenta)", value: "secondary" },
{ label: "Tertiary (green)", value: "tertiary" },
],
},
],
};

View File

@@ -0,0 +1,33 @@
import type { CollectionConfig } from "payload";
export const ContactSubmissions: CollectionConfig = {
slug: "contactSubmissions",
access: {
read: ({ req: { user } }) => Boolean(user),
update: ({ req: { user } }) => Boolean(user),
delete: ({ req: { user } }) => Boolean(user),
create: () => true,
},
admin: {
useAsTitle: "name",
defaultColumns: ["name", "email", "status", "submittedAt"],
},
fields: [
{ name: "name", type: "text", required: true },
{ name: "email", type: "email", required: true },
{ name: "brief", type: "textarea", required: true },
{ name: "source", type: "text" },
{ name: "submittedAt", type: "date", defaultValue: () => new Date() },
{ name: "ipHash", type: "text" },
{
name: "status",
type: "select",
defaultValue: "new",
options: [
{ label: "New", value: "new" },
{ label: "Replied", value: "replied" },
{ label: "Spam", value: "spam" },
],
},
],
};

36
src/collections/Gear.ts Normal file
View File

@@ -0,0 +1,36 @@
import type { CollectionConfig } from "payload";
export const Gear: CollectionConfig = {
slug: "gear",
access: { read: () => true },
admin: {
useAsTitle: "name",
defaultColumns: ["name", "type"],
description: "Music / maker gear — decorative only for v0.0.x",
},
fields: [
{ name: "name", type: "text", required: true },
{
name: "type",
type: "select",
options: [
{ label: "Daily driver", value: "daily-driver" },
{ label: "Interface", value: "interface" },
{ label: "Monitor", value: "monitor" },
{ label: "Workbench", value: "workbench" },
],
},
{ name: "notes", type: "textarea" },
{ name: "image", type: "upload", relationTo: "media" },
{
name: "accent",
type: "select",
defaultValue: "tertiary",
options: [
{ label: "Primary", value: "primary" },
{ label: "Secondary", value: "secondary" },
{ label: "Tertiary", value: "tertiary" },
],
},
],
};

26
src/collections/Media.ts Normal file
View File

@@ -0,0 +1,26 @@
import type { CollectionConfig } from "payload";
export const Media: CollectionConfig = {
slug: "media",
access: {
read: () => true,
},
admin: {
useAsTitle: "alt",
},
upload: {
staticDir: "media",
imageSizes: [
{ name: "thumb", width: 400, height: 400, position: "centre" },
{ name: "card", width: 800, height: undefined, position: "centre" },
{ name: "hero", width: 1600, height: undefined, position: "centre" },
{ name: "og", width: 1200, height: 630, position: "centre" },
],
adminThumbnail: "thumb",
mimeTypes: ["image/*"],
},
fields: [
{ name: "alt", type: "text", required: true },
{ name: "credit", type: "text" },
],
};

43
src/collections/Posts.ts Normal file
View File

@@ -0,0 +1,43 @@
import type { CollectionConfig } from "payload";
export const Posts: CollectionConfig = {
slug: "posts",
access: {
read: ({ req: { user } }) =>
user ? true : { status: { equals: "published" } },
},
admin: {
useAsTitle: "title",
defaultColumns: ["title", "status", "publishedAt"],
},
versions: { drafts: true },
fields: [
{ name: "title", type: "text", required: true },
{ name: "slug", type: "text", required: true, unique: true, index: true },
{ name: "excerpt", type: "textarea" },
{ name: "body", type: "richText" },
{ name: "category", type: "relationship", relationTo: "categories" },
{ name: "heroImage", type: "upload", relationTo: "media" },
{ name: "tags", type: "array", fields: [{ name: "tag", type: "text" }] },
{
name: "status",
type: "select",
defaultValue: "draft",
required: true,
options: [
{ label: "Draft", value: "draft" },
{ label: "Published", value: "published" },
],
},
{ name: "publishedAt", type: "date" },
{
name: "seo",
type: "group",
fields: [
{ name: "title", type: "text" },
{ name: "description", type: "textarea" },
{ name: "image", type: "upload", relationTo: "media" },
],
},
],
};

View File

@@ -0,0 +1,64 @@
import type { CollectionConfig } from "payload";
export const Projects: CollectionConfig = {
slug: "projects",
access: {
read: ({ req: { user } }) =>
user ? true : { status: { equals: "published" } },
},
admin: {
useAsTitle: "title",
defaultColumns: ["title", "status", "featured", "order", "publishedAt"],
},
versions: { drafts: true },
fields: [
{ name: "title", type: "text", required: true },
{ name: "slug", type: "text", required: true, unique: true, index: true },
{
name: "role",
type: "select",
options: [
{ label: "Founder / CEO", value: "founder" },
{ label: "Consultant", value: "consultant" },
{ label: "Engineer", value: "engineer" },
{ label: "Infrastructure", value: "infra" },
],
},
{ name: "category", type: "relationship", relationTo: "categories" },
{ name: "summary", type: "textarea" },
{ name: "body", type: "richText" },
{ name: "stack", type: "array", fields: [{ name: "name", type: "text" }] },
{ name: "heroImage", type: "upload", relationTo: "media" },
{
name: "gallery",
type: "array",
fields: [
{ name: "image", type: "upload", relationTo: "media", required: true },
{ name: "caption", type: "text" },
],
},
{ name: "externalUrl", type: "text" },
{ name: "featured", type: "checkbox", defaultValue: false },
{ name: "order", type: "number", defaultValue: 0 },
{
name: "status",
type: "select",
defaultValue: "draft",
required: true,
options: [
{ label: "Draft", value: "draft" },
{ label: "Published", value: "published" },
],
},
{ name: "publishedAt", type: "date" },
{
name: "seo",
type: "group",
fields: [
{ name: "title", type: "text" },
{ name: "description", type: "textarea" },
{ name: "image", type: "upload", relationTo: "media" },
],
},
],
};

21
src/collections/Users.ts Normal file
View File

@@ -0,0 +1,21 @@
import type { CollectionConfig } from "payload";
export const Users: CollectionConfig = {
slug: "users",
admin: {
useAsTitle: "email",
defaultColumns: ["email", "role"],
},
auth: true,
fields: [
{
name: "role",
type: "select",
defaultValue: "admin",
options: [{ label: "Admin", value: "admin" }],
access: {
update: ({ req: { user } }) => user?.role === "admin",
},
},
],
};