create-goodfellow 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +15 -2
- package/bin/create-goodfellow.js +2 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +220 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +2 -0
- package/dist/scaffold-BGxzPdN1.js +150 -0
- package/package.json +55 -3
- package/templates/next/.github/workflows/deploy.yml +86 -0
- package/templates/next/.gitlab-ci.yml +28 -0
- package/templates/next/README.md +127 -0
- package/templates/next/_gitignore +5 -0
- package/templates/next/app/(site)/[[...path]]/page.tsx +8 -0
- package/templates/next/app/(site)/layout.tsx +5 -0
- package/templates/next/app/admin/demo-content.json/route.ts +5 -0
- package/templates/next/app/admin/layout.tsx +8 -0
- package/templates/next/app/admin/page.tsx +8 -0
- package/templates/next/app/layout.tsx +11 -0
- package/templates/next/app/not-found.tsx +4 -0
- package/templates/next/app/robots.ts +4 -0
- package/templates/next/app/site.css +11 -0
- package/templates/next/app/sitemap.ts +4 -0
- package/templates/next/blocks/installed/index.ts +7 -0
- package/templates/next/components.json +24 -0
- package/templates/next/content/collections/news/_collection.json +113 -0
- package/templates/next/content/collections/news/open-house.json +9 -0
- package/templates/next/content/collections/news/welcome.json +10 -0
- package/templates/next/content/layout/footer.json +55 -0
- package/templates/next/content/layout/header.json +54 -0
- package/templates/next/content/menus.json +25 -0
- package/templates/next/content/pages/404.json +73 -0
- package/templates/next/content/pages/about.json +59 -0
- package/templates/next/content/pages/index.json +215 -0
- package/templates/next/content/pages/news.json +55 -0
- package/templates/next/content/site.json +25 -0
- package/templates/next/content/styles/custom.css +4 -0
- package/templates/next/goodfellow.config.tsx +17 -0
- package/templates/next/lib/site.ts +5 -0
- package/templates/next/next.config.ts +7 -0
- package/templates/next/package.json +40 -0
- package/templates/next/postcss.config.mjs +3 -0
- package/templates/next/public/media/favicon.svg +1 -0
- package/templates/next/public/media/logo.svg +1 -0
- package/templates/next/public/media/placeholder.svg +1 -0
- package/templates/next/tsconfig.json +27 -0
- package/templates/parish/.github/workflows/deploy.yml +84 -0
- package/templates/parish/.gitlab-ci.yml +28 -0
- package/templates/parish/README.md +128 -0
- package/templates/parish/_gitignore +2 -0
- package/templates/parish/blocks/installed/index.ts +7 -0
- package/templates/parish/blocks/mass-times.tsx +59 -0
- package/templates/parish/blocks/notice.tsx +46 -0
- package/templates/parish/blocks/scripture.tsx +40 -0
- package/templates/parish/components.json +24 -0
- package/templates/parish/content/collections/bulletins/2026-09-27.json +8 -0
- package/templates/parish/content/collections/bulletins/2026-10-04.json +8 -0
- package/templates/parish/content/collections/bulletins/_collection.json +113 -0
- package/templates/parish/content/collections/events/_collection.json +156 -0
- package/templates/parish/content/collections/events/advent-penance-service.json +14 -0
- package/templates/parish/content/collections/events/all-souls.json +14 -0
- package/templates/parish/content/collections/events/christmas-concert.json +14 -0
- package/templates/parish/content/collections/events/fall-festival.json +14 -0
- package/templates/parish/content/collections/events/youth-group.json +23 -0
- package/templates/parish/content/collections/news/_collection.json +137 -0
- package/templates/parish/content/collections/news/bell-tower-repairs.json +13 -0
- package/templates/parish/content/collections/news/choir-new-voices.json +14 -0
- package/templates/parish/content/collections/news/food-drive.json +13 -0
- package/templates/parish/content/collections/news/new-website.json +13 -0
- package/templates/parish/content/collections/news/winter-coats.json +13 -0
- package/templates/parish/content/collections/news/youth-group.json +13 -0
- package/templates/parish/content/collections/news/youth-service-day.json +14 -0
- package/templates/parish/content/collections/staff/_collection.json +34 -0
- package/templates/parish/content/collections/staff/david-okafor.json +9 -0
- package/templates/parish/content/collections/staff/fr-thomas-reed.json +9 -0
- package/templates/parish/content/collections/staff/maria-chen.json +9 -0
- package/templates/parish/content/collections/staff/sarah-lindqvist.json +9 -0
- package/templates/parish/content/layout/footer.json +142 -0
- package/templates/parish/content/layout/header.json +54 -0
- package/templates/parish/content/menus.json +67 -0
- package/templates/parish/content/pages/404.json +85 -0
- package/templates/parish/content/pages/about.json +153 -0
- package/templates/parish/content/pages/bulletins.json +64 -0
- package/templates/parish/content/pages/calendar.json +59 -0
- package/templates/parish/content/pages/contact.json +180 -0
- package/templates/parish/content/pages/events.json +107 -0
- package/templates/parish/content/pages/index.json +390 -0
- package/templates/parish/content/pages/mass-times.json +168 -0
- package/templates/parish/content/pages/news.json +68 -0
- package/templates/parish/content/pages/sacraments.json +259 -0
- package/templates/parish/content/site.json +36 -0
- package/templates/parish/content/styles/custom.css +4 -0
- package/templates/parish/goodfellow.config.tsx +24 -0
- package/templates/parish/package.json +36 -0
- package/templates/parish/public/media/bulletin-example.pdf +32 -0
- package/templates/parish/public/media/candles.svg +22 -0
- package/templates/parish/public/media/church.svg +33 -0
- package/templates/parish/public/media/favicon.svg +5 -0
- package/templates/parish/public/media/gathering.svg +18 -0
- package/templates/parish/public/media/logo.svg +5 -0
- package/templates/parish/public/media/person.svg +5 -0
- package/templates/parish/public/media/placeholder.svg +5 -0
- package/templates/parish/src/styles.css +8 -0
- package/templates/parish/tsconfig.json +14 -0
- package/templates/parish/vercel.ts +65 -0
- package/templates/registry/accordion.json +17 -0
- package/templates/registry/alert.json +16 -0
- package/templates/registry/badge.json +17 -0
- package/templates/registry/button.json +17 -0
- package/templates/registry/card.json +16 -0
- package/templates/registry/carousel.json +19 -0
- package/templates/registry/custom-html.json +31 -0
- package/templates/registry/registry.json +364 -0
- package/templates/registry/shadcn-call-to-action.json +26 -0
- package/templates/registry/shadcn-cards.json +26 -0
- package/templates/registry/shadcn-carousel.json +29 -0
- package/templates/registry/shadcn-faq.json +30 -0
- package/templates/registry/shadcn-hero.json +25 -0
- package/templates/registry/shadcn-notice.json +27 -0
- package/templates/registry/shadcn-pricing.json +28 -0
- package/templates/registry/shadcn-tabs.json +30 -0
- package/templates/registry/shadcn-testimonials.json +25 -0
- package/templates/registry/tabs.json +17 -0
- package/templates/starter/.github/workflows/deploy.yml +84 -0
- package/templates/starter/.gitlab-ci.yml +28 -0
- package/templates/starter/README.md +108 -0
- package/templates/starter/_gitignore +2 -0
- package/templates/starter/blocks/installed/index.ts +7 -0
- package/templates/starter/components.json +24 -0
- package/templates/starter/content/collections/news/_collection.json +113 -0
- package/templates/starter/content/collections/news/open-house.json +9 -0
- package/templates/starter/content/collections/news/welcome.json +10 -0
- package/templates/starter/content/layout/footer.json +55 -0
- package/templates/starter/content/layout/header.json +54 -0
- package/templates/starter/content/menus.json +25 -0
- package/templates/starter/content/pages/404.json +73 -0
- package/templates/starter/content/pages/about.json +59 -0
- package/templates/starter/content/pages/index.json +215 -0
- package/templates/starter/content/pages/news.json +55 -0
- package/templates/starter/content/site.json +25 -0
- package/templates/starter/content/styles/custom.css +4 -0
- package/templates/starter/goodfellow.config.tsx +17 -0
- package/templates/starter/package.json +36 -0
- package/templates/starter/public/media/favicon.svg +1 -0
- package/templates/starter/public/media/logo.svg +1 -0
- package/templates/starter/public/media/placeholder.svg +1 -0
- package/templates/starter/src/styles.css +8 -0
- package/templates/starter/tsconfig.json +14 -0
- package/templates/starter/vercel.ts +65 -0
- package/templates/versions.json +13 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"data": {
|
|
4
|
+
"content": [
|
|
5
|
+
{
|
|
6
|
+
"type": "Section",
|
|
7
|
+
"props": {
|
|
8
|
+
"id": "Section-header",
|
|
9
|
+
"background": "none",
|
|
10
|
+
"backgroundImage": "",
|
|
11
|
+
"className": "",
|
|
12
|
+
"content": [
|
|
13
|
+
{
|
|
14
|
+
"type": "Flex",
|
|
15
|
+
"props": {
|
|
16
|
+
"id": "Flex-header",
|
|
17
|
+
"align": "center",
|
|
18
|
+
"className": "",
|
|
19
|
+
"direction": "row",
|
|
20
|
+
"gap": "md",
|
|
21
|
+
"items": [
|
|
22
|
+
{
|
|
23
|
+
"type": "SiteBrand",
|
|
24
|
+
"props": {
|
|
25
|
+
"id": "SiteBrand-header",
|
|
26
|
+
"className": "",
|
|
27
|
+
"show": "both"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"type": "Menu",
|
|
32
|
+
"props": {
|
|
33
|
+
"id": "Menu-main",
|
|
34
|
+
"className": "",
|
|
35
|
+
"menu": "main",
|
|
36
|
+
"orientation": "horizontal"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"justify": "between",
|
|
41
|
+
"wrap": true
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"padding": "sm",
|
|
46
|
+
"width": "wide"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
"root": {
|
|
51
|
+
"props": {}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"menus": {
|
|
4
|
+
"footer": [
|
|
5
|
+
{
|
|
6
|
+
"href": "/about",
|
|
7
|
+
"label": "About"
|
|
8
|
+
}
|
|
9
|
+
],
|
|
10
|
+
"main": [
|
|
11
|
+
{
|
|
12
|
+
"href": "/",
|
|
13
|
+
"label": "Home"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"href": "/about",
|
|
17
|
+
"label": "About"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"href": "/news",
|
|
21
|
+
"label": "News"
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"data": {
|
|
4
|
+
"content": [
|
|
5
|
+
{
|
|
6
|
+
"type": "Section",
|
|
7
|
+
"props": {
|
|
8
|
+
"id": "Section-not-found",
|
|
9
|
+
"background": "none",
|
|
10
|
+
"backgroundImage": "",
|
|
11
|
+
"className": "",
|
|
12
|
+
"content": [
|
|
13
|
+
{
|
|
14
|
+
"type": "Heading",
|
|
15
|
+
"props": {
|
|
16
|
+
"id": "Heading-not-found",
|
|
17
|
+
"align": "center",
|
|
18
|
+
"className": "",
|
|
19
|
+
"level": "h1",
|
|
20
|
+
"text": "Page not found"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"type": "Text",
|
|
25
|
+
"props": {
|
|
26
|
+
"id": "Text-not-found",
|
|
27
|
+
"align": "center",
|
|
28
|
+
"className": "mt-4 text-muted-foreground",
|
|
29
|
+
"content": "<p>The page you're looking for doesn't exist or has moved.</p>"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"type": "Flex",
|
|
34
|
+
"props": {
|
|
35
|
+
"id": "Flex-not-found",
|
|
36
|
+
"align": "center",
|
|
37
|
+
"className": "mt-8",
|
|
38
|
+
"direction": "row",
|
|
39
|
+
"gap": "md",
|
|
40
|
+
"items": [
|
|
41
|
+
{
|
|
42
|
+
"type": "Button",
|
|
43
|
+
"props": {
|
|
44
|
+
"id": "Button-home",
|
|
45
|
+
"className": "",
|
|
46
|
+
"href": "/",
|
|
47
|
+
"label": "Go to the home page",
|
|
48
|
+
"newTab": false,
|
|
49
|
+
"size": "md",
|
|
50
|
+
"variant": "primary"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"justify": "center",
|
|
55
|
+
"wrap": true
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
],
|
|
59
|
+
"padding": "lg",
|
|
60
|
+
"width": "narrow"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"root": {
|
|
65
|
+
"props": {
|
|
66
|
+
"className": "",
|
|
67
|
+
"description": "",
|
|
68
|
+
"image": "",
|
|
69
|
+
"title": "Page not found"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"data": {
|
|
4
|
+
"content": [
|
|
5
|
+
{
|
|
6
|
+
"type": "Section",
|
|
7
|
+
"props": {
|
|
8
|
+
"id": "Section-about",
|
|
9
|
+
"background": "none",
|
|
10
|
+
"backgroundImage": "",
|
|
11
|
+
"className": "",
|
|
12
|
+
"content": [
|
|
13
|
+
{
|
|
14
|
+
"type": "Heading",
|
|
15
|
+
"props": {
|
|
16
|
+
"id": "Heading-about",
|
|
17
|
+
"align": "left",
|
|
18
|
+
"className": "",
|
|
19
|
+
"level": "h1",
|
|
20
|
+
"text": "About us"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"type": "Text",
|
|
25
|
+
"props": {
|
|
26
|
+
"id": "Text-about",
|
|
27
|
+
"align": "left",
|
|
28
|
+
"className": "mt-6",
|
|
29
|
+
"content": "<p>Tell visitors who you are. This text supports <strong>bold</strong>, <em>italics</em>, lists and <a href=\"/\">links</a>.</p><ul><li>Founded in 2026</li><li>Based wherever you are</li></ul>"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"type": "Image",
|
|
34
|
+
"props": {
|
|
35
|
+
"id": "Image-about",
|
|
36
|
+
"alt": "",
|
|
37
|
+
"aspect": "wide",
|
|
38
|
+
"caption": "Replace this image with one of your own.",
|
|
39
|
+
"className": "mt-8",
|
|
40
|
+
"rounded": true,
|
|
41
|
+
"src": "/media/placeholder.svg"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"padding": "lg",
|
|
46
|
+
"width": "narrow"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
"root": {
|
|
51
|
+
"props": {
|
|
52
|
+
"className": "",
|
|
53
|
+
"description": "Who we are and what we do.",
|
|
54
|
+
"image": "",
|
|
55
|
+
"title": "About us"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"data": {
|
|
4
|
+
"content": [
|
|
5
|
+
{
|
|
6
|
+
"type": "Section",
|
|
7
|
+
"props": {
|
|
8
|
+
"id": "Section-hero",
|
|
9
|
+
"background": "primary",
|
|
10
|
+
"backgroundImage": "",
|
|
11
|
+
"className": "",
|
|
12
|
+
"content": [
|
|
13
|
+
{
|
|
14
|
+
"type": "Heading",
|
|
15
|
+
"props": {
|
|
16
|
+
"id": "Heading-hero",
|
|
17
|
+
"align": "left",
|
|
18
|
+
"className": "",
|
|
19
|
+
"level": "h1",
|
|
20
|
+
"text": "Welcome to my site"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"type": "Text",
|
|
25
|
+
"props": {
|
|
26
|
+
"id": "Text-hero",
|
|
27
|
+
"align": "left",
|
|
28
|
+
"className": "mt-4 max-w-2xl text-lg opacity-90",
|
|
29
|
+
"content": "<p>This page is stored as a file in your site's repository. Edit it in the admin panel, or change <code>content/pages/index.json</code> directly.</p>"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"type": "Flex",
|
|
34
|
+
"props": {
|
|
35
|
+
"id": "Flex-hero",
|
|
36
|
+
"align": "center",
|
|
37
|
+
"className": "mt-8",
|
|
38
|
+
"direction": "row",
|
|
39
|
+
"gap": "md",
|
|
40
|
+
"items": [
|
|
41
|
+
{
|
|
42
|
+
"type": "Button",
|
|
43
|
+
"props": {
|
|
44
|
+
"id": "Button-primary",
|
|
45
|
+
"className": "",
|
|
46
|
+
"href": "/about",
|
|
47
|
+
"label": "About us",
|
|
48
|
+
"newTab": false,
|
|
49
|
+
"size": "lg",
|
|
50
|
+
"variant": "secondary"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"type": "Button",
|
|
55
|
+
"props": {
|
|
56
|
+
"id": "Button-secondary",
|
|
57
|
+
"className": "",
|
|
58
|
+
"href": "/about",
|
|
59
|
+
"label": "Contact",
|
|
60
|
+
"newTab": false,
|
|
61
|
+
"size": "lg",
|
|
62
|
+
"variant": "outline"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"justify": "start",
|
|
67
|
+
"wrap": true
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
"padding": "lg",
|
|
72
|
+
"width": "normal"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"type": "Section",
|
|
77
|
+
"props": {
|
|
78
|
+
"id": "Section-features",
|
|
79
|
+
"background": "none",
|
|
80
|
+
"backgroundImage": "",
|
|
81
|
+
"className": "",
|
|
82
|
+
"content": [
|
|
83
|
+
{
|
|
84
|
+
"type": "Heading",
|
|
85
|
+
"props": {
|
|
86
|
+
"id": "Heading-features",
|
|
87
|
+
"align": "center",
|
|
88
|
+
"className": "mb-10",
|
|
89
|
+
"level": "h2",
|
|
90
|
+
"text": "Everything in one place"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"type": "Grid",
|
|
95
|
+
"props": {
|
|
96
|
+
"id": "Grid-features",
|
|
97
|
+
"className": "",
|
|
98
|
+
"columns": "3",
|
|
99
|
+
"gap": "md",
|
|
100
|
+
"items": [
|
|
101
|
+
{
|
|
102
|
+
"type": "Section",
|
|
103
|
+
"props": {
|
|
104
|
+
"id": "Section-feature-1",
|
|
105
|
+
"background": "none",
|
|
106
|
+
"backgroundImage": "",
|
|
107
|
+
"className": "rounded-lg border px-2 py-6",
|
|
108
|
+
"content": [
|
|
109
|
+
{
|
|
110
|
+
"type": "Heading",
|
|
111
|
+
"props": {
|
|
112
|
+
"id": "Heading-feature-1",
|
|
113
|
+
"align": "left",
|
|
114
|
+
"className": "",
|
|
115
|
+
"level": "h3",
|
|
116
|
+
"text": "Pages"
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"type": "Text",
|
|
121
|
+
"props": {
|
|
122
|
+
"id": "Text-feature-1",
|
|
123
|
+
"align": "left",
|
|
124
|
+
"className": "mt-2 text-muted-foreground",
|
|
125
|
+
"content": "<p>Build pages from blocks: sections, columns, text, images and buttons.</p>"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
],
|
|
129
|
+
"padding": "none",
|
|
130
|
+
"width": "full"
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"type": "Section",
|
|
135
|
+
"props": {
|
|
136
|
+
"id": "Section-feature-2",
|
|
137
|
+
"background": "none",
|
|
138
|
+
"backgroundImage": "",
|
|
139
|
+
"className": "rounded-lg border px-2 py-6",
|
|
140
|
+
"content": [
|
|
141
|
+
{
|
|
142
|
+
"type": "Heading",
|
|
143
|
+
"props": {
|
|
144
|
+
"id": "Heading-feature-2",
|
|
145
|
+
"align": "left",
|
|
146
|
+
"className": "",
|
|
147
|
+
"level": "h3",
|
|
148
|
+
"text": "Your design"
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"type": "Text",
|
|
153
|
+
"props": {
|
|
154
|
+
"id": "Text-feature-2",
|
|
155
|
+
"align": "left",
|
|
156
|
+
"className": "mt-2 text-muted-foreground",
|
|
157
|
+
"content": "<p>Set colors and fonts once in the site settings, and every page follows.</p>"
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
],
|
|
161
|
+
"padding": "none",
|
|
162
|
+
"width": "full"
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"type": "Section",
|
|
167
|
+
"props": {
|
|
168
|
+
"id": "Section-feature-3",
|
|
169
|
+
"background": "none",
|
|
170
|
+
"backgroundImage": "",
|
|
171
|
+
"className": "rounded-lg border px-2 py-6",
|
|
172
|
+
"content": [
|
|
173
|
+
{
|
|
174
|
+
"type": "Heading",
|
|
175
|
+
"props": {
|
|
176
|
+
"id": "Heading-feature-3",
|
|
177
|
+
"align": "left",
|
|
178
|
+
"className": "",
|
|
179
|
+
"level": "h3",
|
|
180
|
+
"text": "No hosting bills"
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"type": "Text",
|
|
185
|
+
"props": {
|
|
186
|
+
"id": "Text-feature-3",
|
|
187
|
+
"align": "left",
|
|
188
|
+
"className": "mt-2 text-muted-foreground",
|
|
189
|
+
"content": "<p>The whole site is static files, so free hosting is enough.</p>"
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
],
|
|
193
|
+
"padding": "none",
|
|
194
|
+
"width": "full"
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
]
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
],
|
|
201
|
+
"padding": "lg",
|
|
202
|
+
"width": "normal"
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
],
|
|
206
|
+
"root": {
|
|
207
|
+
"props": {
|
|
208
|
+
"className": "",
|
|
209
|
+
"description": "",
|
|
210
|
+
"image": "",
|
|
211
|
+
"title": "Welcome"
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"data": {
|
|
4
|
+
"content": [
|
|
5
|
+
{
|
|
6
|
+
"type": "Section",
|
|
7
|
+
"props": {
|
|
8
|
+
"id": "Section-news-list",
|
|
9
|
+
"background": "none",
|
|
10
|
+
"backgroundImage": "",
|
|
11
|
+
"className": "",
|
|
12
|
+
"content": [
|
|
13
|
+
{
|
|
14
|
+
"type": "Heading",
|
|
15
|
+
"props": {
|
|
16
|
+
"id": "Heading-news",
|
|
17
|
+
"align": "left",
|
|
18
|
+
"className": "",
|
|
19
|
+
"level": "h1",
|
|
20
|
+
"text": "News"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"type": "CollectionList",
|
|
25
|
+
"props": {
|
|
26
|
+
"id": "CollectionList-news",
|
|
27
|
+
"className": "mt-8",
|
|
28
|
+
"collection": "news",
|
|
29
|
+
"columns": "3",
|
|
30
|
+
"dateField": "date",
|
|
31
|
+
"emptyText": "No news yet.",
|
|
32
|
+
"imageField": "image",
|
|
33
|
+
"layout": "cards",
|
|
34
|
+
"limit": 0,
|
|
35
|
+
"order": "default",
|
|
36
|
+
"show": "all",
|
|
37
|
+
"summaryField": "summary"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"padding": "lg",
|
|
42
|
+
"width": "normal"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"root": {
|
|
47
|
+
"props": {
|
|
48
|
+
"className": "",
|
|
49
|
+
"description": "The latest news.",
|
|
50
|
+
"image": "",
|
|
51
|
+
"title": "News"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"description": "A website built with Goodfellow.",
|
|
4
|
+
"favicon": "/media/favicon.svg",
|
|
5
|
+
"language": "en",
|
|
6
|
+
"logo": {
|
|
7
|
+
"alt": "My site",
|
|
8
|
+
"src": "/media/logo.svg"
|
|
9
|
+
},
|
|
10
|
+
"theme": {
|
|
11
|
+
"colors": {
|
|
12
|
+
"border": "#e2e8f0",
|
|
13
|
+
"muted": "#f1f5f9",
|
|
14
|
+
"mutedForeground": "#64748b",
|
|
15
|
+
"primary": "#1e3a8a",
|
|
16
|
+
"primaryForeground": "#ffffff"
|
|
17
|
+
},
|
|
18
|
+
"fonts": {
|
|
19
|
+
"body": "Inter",
|
|
20
|
+
"heading": "Fraunces"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"title": "My site",
|
|
24
|
+
"titleTemplate": "%s | My site"
|
|
25
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { blocks, categories } from "@goodfellow-cms/blocks";
|
|
2
|
+
import { defineConfig } from "@goodfellow-cms/core";
|
|
3
|
+
// import { github } from "@goodfellow-cms/github";
|
|
4
|
+
// import { gitlab } from "@goodfellow-cms/gitlab";
|
|
5
|
+
import { installedBlocks, installedCategories } from "./blocks/installed";
|
|
6
|
+
|
|
7
|
+
export default defineConfig({
|
|
8
|
+
// The built-in blocks, and those installed from the admin panel's Blocks screen.
|
|
9
|
+
// Add your own here too, e.g. `blocks: { ...blocks, ...installedBlocks, MassTimes }`.
|
|
10
|
+
blocks: { ...blocks, ...installedBlocks },
|
|
11
|
+
categories: { ...categories, ...installedCategories },
|
|
12
|
+
|
|
13
|
+
// Where the site is stored. Once this is set, builds include the admin panel at /admin.
|
|
14
|
+
// See README.md for how to set up sign-in.
|
|
15
|
+
// backend: github({ repo: "your-name/your-site" }),
|
|
16
|
+
// backend: gitlab({ project: "your-name/your-site", clientId: "your-application-id" }),
|
|
17
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@goodfellow-cms/template-starter",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "goodfellow dev",
|
|
8
|
+
"build": "goodfellow build",
|
|
9
|
+
"preview": "goodfellow preview",
|
|
10
|
+
"typecheck": "tsc -p tsconfig.json"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@goodfellow-cms/admin": "workspace:*",
|
|
14
|
+
"@goodfellow-cms/blocks": "workspace:*",
|
|
15
|
+
"@goodfellow-cms/core": "workspace:*",
|
|
16
|
+
"@goodfellow-cms/github": "workspace:*",
|
|
17
|
+
"@goodfellow-cms/gitlab": "workspace:*",
|
|
18
|
+
"@goodfellow-cms/react": "workspace:*",
|
|
19
|
+
"@puckeditor/core": "0.23.0",
|
|
20
|
+
"class-variance-authority": "0.7.1",
|
|
21
|
+
"clsx": "2.1.1",
|
|
22
|
+
"cn": "0.4.0",
|
|
23
|
+
"embla-carousel-react": "8.6.0",
|
|
24
|
+
"lucide-react": "1.52.0",
|
|
25
|
+
"radix-ui": "1.7.0",
|
|
26
|
+
"react": "19.3.0",
|
|
27
|
+
"react-dom": "19.3.0",
|
|
28
|
+
"tailwind-merge": "3.7.0",
|
|
29
|
+
"tailwindcss": "4.3.3",
|
|
30
|
+
"tw-animate-css": "1.4.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"goodfellow": "workspace:*",
|
|
34
|
+
"@types/react": "^19.2.0"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect width="40" height="40" rx="10" fill="#1e3a8a"/><path d="M12 28V12h6.5a5 5 0 0 1 0 10H16v6zm4-9.5h2.4a1.75 1.75 0 0 0 0-3.5H16z" fill="#fff"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect width="40" height="40" rx="10" fill="#1e3a8a"/><path d="M12 28V12h6.5a5 5 0 0 1 0 10H16v6zm4-9.5h2.4a1.75 1.75 0 0 0 0-3.5H16z" fill="#fff"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 450"><rect width="800" height="450" fill="#e2e8f0"/><path d="M0 450 260 210l140 130 110-90 290 200z" fill="#cbd5e1"/><circle cx="600" cy="130" r="50" fill="#cbd5e1"/></svg>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
/* Animations for blocks installed from block registries, such as an FAQ's opening answers. */
|
|
3
|
+
@import "tw-animate-css";
|
|
4
|
+
@import "@goodfellow-cms/react/theme.css";
|
|
5
|
+
@import "@goodfellow-cms/blocks/styles.css";
|
|
6
|
+
|
|
7
|
+
/* Lets Tailwind find class names typed into the editor. */
|
|
8
|
+
@source "../content";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"jsx": "react-jsx",
|
|
7
|
+
"strict": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"noEmit": true,
|
|
10
|
+
// As in shadcn/ui projects: blocks installed from block registries import from "@/components/ui/…".
|
|
11
|
+
"paths": { "@/*": ["./*"] }
|
|
12
|
+
},
|
|
13
|
+
"include": ["goodfellow.config.tsx", "blocks", "components", "lib", "hooks"]
|
|
14
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Vercel's settings for this site, which Vercel reads when it builds the site.
|
|
2
|
+
//
|
|
3
|
+
// Vercel also sends the redirects from Site Settings → Redirects (content/redirects.json) itself,
|
|
4
|
+
// so visitors go straight to the new address. Like the pages the build writes at old addresses
|
|
5
|
+
// for other hosts, a redirect from an address a page has is left out: pages always win.
|
|
6
|
+
// This file uses only Node's own modules, since Vercel may read it before installing packages.
|
|
7
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
|
|
10
|
+
export const config = {
|
|
11
|
+
framework: null,
|
|
12
|
+
installCommand: "npm ci",
|
|
13
|
+
buildCommand: "npx goodfellow build",
|
|
14
|
+
outputDirectory: "dist",
|
|
15
|
+
redirects: redirects(),
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
interface Redirect {
|
|
19
|
+
from: string;
|
|
20
|
+
to: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function readJson(file: string): Record<string, unknown> | undefined {
|
|
24
|
+
return existsSync(file) ? JSON.parse(readFileSync(file, "utf8")) : undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Every file in a folder and its folders, as paths inside it. */
|
|
28
|
+
function filesIn(dir: string): string[] {
|
|
29
|
+
if (!existsSync(dir)) return [];
|
|
30
|
+
return readdirSync(dir, { recursive: true, encoding: "utf8" }).map((file) => file.split("\\").join("/"));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** The addresses that have pages: `content/pages/about.json` is /about, and each collection item has its own. */
|
|
34
|
+
function pageAddresses(): Set<string> {
|
|
35
|
+
const addresses = new Set<string>();
|
|
36
|
+
for (const file of filesIn("content/pages")) {
|
|
37
|
+
if (file.endsWith(".json")) addresses.add(`/${file.slice(0, -".json".length)}`.replace(/\/?index$/, "") || "/");
|
|
38
|
+
}
|
|
39
|
+
for (const id of filesIn("content/collections").filter((file) => file.endsWith("/_collection.json"))) {
|
|
40
|
+
const folder = id.slice(0, -"/_collection.json".length);
|
|
41
|
+
const pattern = readJson(join("content/collections", id))?.path;
|
|
42
|
+
if (typeof pattern !== "string") continue;
|
|
43
|
+
for (const file of readdirSync(join("content/collections", folder))) {
|
|
44
|
+
const slug = /^(.+)\.(json|md)$/.exec(file)?.[1];
|
|
45
|
+
if (slug && file !== "_collection.json") addresses.add(pattern.replace("{slug}", slug).replace(/\/+$/, ""));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return addresses;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** An address as Vercel matches it, with the characters its patterns use escaped. */
|
|
52
|
+
function source(path: string): string {
|
|
53
|
+
return encodeURI(path).replace(/[()[\]{}+*?:!]/g, "\\$&");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function redirects() {
|
|
57
|
+
const list = (readJson("content/redirects.json")?.redirects ?? []) as Redirect[];
|
|
58
|
+
const pages = pageAddresses();
|
|
59
|
+
return list.flatMap(({ from, to }) => {
|
|
60
|
+
const path = from.replace(/\/+$/, "");
|
|
61
|
+
if (pages.has(path)) return [];
|
|
62
|
+
// With and without a trailing slash, as the other hosts serve the page there.
|
|
63
|
+
return [path, `${path}/`].map((address) => ({ source: source(address), destination: to, permanent: true }));
|
|
64
|
+
});
|
|
65
|
+
}
|