EmDash installed - server mode, basic integration. Visual editor wiring deferred to fix build errors.
This commit is contained in:
@@ -32,7 +32,7 @@
|
|||||||
"runtime": "Node.js 22.12.0"
|
"runtime": "Node.js 22.12.0"
|
||||||
},
|
},
|
||||||
"build": {
|
"build": {
|
||||||
"buildCommand": "npm run build 2>&1 | tail -8",
|
"buildCommand": "pkill -f \"node.*entry.mjs\" 2>/dev/null; sleep 1; npm run build 2>&1 | tail -10",
|
||||||
"testCommand": null,
|
"testCommand": null,
|
||||||
"lintCommand": null,
|
"lintCommand": null,
|
||||||
"devCommand": "npm run dev",
|
"devCommand": "npm run dev",
|
||||||
@@ -207,6 +207,12 @@
|
|||||||
"lastAccessed": 1777990670077,
|
"lastAccessed": 1777990670077,
|
||||||
"type": "file"
|
"type": "file"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "src/layouts/Base.astro",
|
||||||
|
"accessCount": 4,
|
||||||
|
"lastAccessed": 1778036775836,
|
||||||
|
"type": "file"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "src/styles/global.css",
|
"path": "src/styles/global.css",
|
||||||
"accessCount": 3,
|
"accessCount": 3,
|
||||||
@@ -219,6 +225,12 @@
|
|||||||
"lastAccessed": 1777995178143,
|
"lastAccessed": 1777995178143,
|
||||||
"type": "directory"
|
"type": "directory"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "astro.config.mjs",
|
||||||
|
"accessCount": 2,
|
||||||
|
"lastAccessed": 1778036187649,
|
||||||
|
"type": "file"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "src/pages",
|
"path": "src/pages",
|
||||||
"accessCount": 1,
|
"accessCount": 1,
|
||||||
@@ -230,6 +242,24 @@
|
|||||||
"accessCount": 1,
|
"accessCount": 1,
|
||||||
"lastAccessed": 1778035760907,
|
"lastAccessed": 1778035760907,
|
||||||
"type": "directory"
|
"type": "directory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/live.config.ts",
|
||||||
|
"accessCount": 1,
|
||||||
|
"lastAccessed": 1778036198221,
|
||||||
|
"type": "file"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "seed/seed.json",
|
||||||
|
"accessCount": 1,
|
||||||
|
"lastAccessed": 1778036244021,
|
||||||
|
"type": "file"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/utils/site-identity.ts",
|
||||||
|
"accessCount": 1,
|
||||||
|
"lastAccessed": 1778036594901,
|
||||||
|
"type": "file"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"userDirectives": []
|
"userDirectives": []
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"tool_name": "Bash",
|
"tool_name": "Write",
|
||||||
"tool_input_preview": "{\"command\":\"npm run build 2>&1\",\"timeout\":120000,\"description\":\"Build Astro site to check for errors\"}",
|
"tool_input_preview": "{\"file_path\":\"/Users/kunthawatgleethong/Gitea/moreminimore-emdash/moreminimore-site/src/utils/site-identity.ts\",\"content\":\"import { emdash } from \\\"emdash/astro\\\";\\nimport type { CollectionEntry } fro...",
|
||||||
"error": "Exit code 1",
|
"error": "EACCES: permission denied, mkdir '/Users/kunthawatgleethong'",
|
||||||
"timestamp": "2026-05-05T13:17:02.070Z",
|
"timestamp": "2026-05-06T03:03:02.581Z",
|
||||||
"retry_count": 1
|
"retry_count": 1
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,20 @@
|
|||||||
// @ts-check
|
// @ts-check
|
||||||
import { defineConfig } from 'astro/config';
|
import { defineConfig } from 'astro/config';
|
||||||
|
import node from "@astrojs/node";
|
||||||
|
import react from "@astrojs/react";
|
||||||
|
import emdash, { local } from "emdash/astro";
|
||||||
|
import { sqlite } from "emdash/db";
|
||||||
|
|
||||||
// https://astro.build/config
|
export default defineConfig({
|
||||||
export default defineConfig({});
|
output: "server",
|
||||||
|
adapter: node({ mode: "standalone" }),
|
||||||
|
image: { layout: "constrained", responsiveStyles: true },
|
||||||
|
integrations: [
|
||||||
|
react(),
|
||||||
|
emdash({
|
||||||
|
database: sqlite({ url: "file:./data.db" }),
|
||||||
|
storage: local({ directory: "./uploads", baseUrl: "/_emdash/api/media/file" }),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
devToolbar: { enabled: false },
|
||||||
|
});
|
||||||
39
emdash-env.d.ts
vendored
Normal file
39
emdash-env.d.ts
vendored
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// Generated by EmDash on dev server start
|
||||||
|
// Do not edit manually
|
||||||
|
|
||||||
|
/// <reference types="emdash/locals" />
|
||||||
|
|
||||||
|
import type { ContentBylineCredit, PortableTextBlock } from "emdash";
|
||||||
|
|
||||||
|
export interface Page {
|
||||||
|
id: string;
|
||||||
|
slug: string | null;
|
||||||
|
status: string;
|
||||||
|
title: string;
|
||||||
|
content?: PortableTextBlock[];
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
publishedAt: Date | null;
|
||||||
|
bylines?: ContentBylineCredit[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Post {
|
||||||
|
id: string;
|
||||||
|
slug: string | null;
|
||||||
|
status: string;
|
||||||
|
title: string;
|
||||||
|
featured_image?: { id: string; src?: string; alt?: string; width?: number; height?: number };
|
||||||
|
content?: PortableTextBlock[];
|
||||||
|
excerpt?: string;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
publishedAt: Date | null;
|
||||||
|
bylines?: ContentBylineCredit[];
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "emdash" {
|
||||||
|
interface EmDashCollections {
|
||||||
|
pages: Page;
|
||||||
|
posts: Post;
|
||||||
|
}
|
||||||
|
}
|
||||||
4745
package-lock.json
generated
4745
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,11 @@
|
|||||||
"astro": "astro"
|
"astro": "astro"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"astro": "^6.2.2"
|
"@astrojs/node": "^10.0.6",
|
||||||
|
"@astrojs/react": "^5.0.4",
|
||||||
|
"astro": "^6.2.2",
|
||||||
|
"emdash": "^0.9.0",
|
||||||
|
"react": "^19.2.5",
|
||||||
|
"react-dom": "^19.2.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
85
seed/seed.json
Normal file
85
seed/seed.json
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
{
|
||||||
|
"collections": [
|
||||||
|
{
|
||||||
|
"name": "pages",
|
||||||
|
"label": "Pages",
|
||||||
|
"fields": [
|
||||||
|
{ "name": "title", "type": "string", "label": "Title" },
|
||||||
|
{ "name": "subtitle", "type": "string", "label": "Subtitle" },
|
||||||
|
{ "name": "badge", "type": "string", "label": "Badge" },
|
||||||
|
{ "name": "heroImage", "type": "image", "label": "Hero Image" },
|
||||||
|
{ "name": "theme", "type": "select", "label": "Theme", "options": ["yellow", "accent"] },
|
||||||
|
{ "name": "showCTA", "type": "boolean", "label": "Show CTA" },
|
||||||
|
{ "name": "ctaText", "type": "string", "label": "CTA Text" },
|
||||||
|
{ "name": "ctaLink", "type": "string", "label": "CTA Link" },
|
||||||
|
{ "name": "variant", "type": "select", "label": "Hero Variant", "options": ["split", "centered", "text-only", "floating-cards"] },
|
||||||
|
{ "name": "size", "type": "select", "label": "Hero Size", "options": ["full", "compact"] }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "services",
|
||||||
|
"label": "Services",
|
||||||
|
"fields": [
|
||||||
|
{ "name": "title", "type": "string", "label": "Title" },
|
||||||
|
{ "name": "subtitle", "type": "string", "label": "Subtitle" },
|
||||||
|
{ "name": "badge", "type": "string", "label": "Badge" },
|
||||||
|
{ "name": "heroImage", "type": "image", "label": "Hero Image" },
|
||||||
|
{ "name": "content", "type": "richtext", "label": "Content" },
|
||||||
|
{ "name": "features", "type": "array", "label": "Features", "fields": [
|
||||||
|
{ "name": "icon", "type": "string", "label": "Icon" },
|
||||||
|
{ "name": "title", "type": "string", "label": "Title" },
|
||||||
|
{ "name": "description", "type": "string", "label": "Description" }
|
||||||
|
]}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "portfolio",
|
||||||
|
"label": "Portfolio",
|
||||||
|
"fields": [
|
||||||
|
{ "name": "name", "type": "string", "label": "Name" },
|
||||||
|
{ "name": "url", "type": "string", "label": "URL" },
|
||||||
|
{ "name": "category", "type": "select", "label": "Category", "options": ["webdev", "ecommerce", "marketing"] },
|
||||||
|
{ "name": "categoryLabel", "type": "string", "label": "Category Label" },
|
||||||
|
{ "name": "thumbnail", "type": "image", "label": "Thumbnail" },
|
||||||
|
{ "name": "description", "type": "string", "label": "Description" },
|
||||||
|
{ "name": "services", "type": "array", "label": "Services", "fields": [
|
||||||
|
{ "name": "name", "type": "string", "label": "Name" }
|
||||||
|
]}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "blog",
|
||||||
|
"label": "Blog",
|
||||||
|
"fields": [
|
||||||
|
{ "name": "title", "type": "string", "label": "Title" },
|
||||||
|
{ "name": "excerpt", "type": "string", "label": "Excerpt" },
|
||||||
|
{ "name": "image", "type": "image", "label": "Image" },
|
||||||
|
{ "name": "date", "type": "date", "label": "Date" },
|
||||||
|
{ "name": "category", "type": "string", "label": "Category" },
|
||||||
|
{ "name": "content", "type": "richtext", "label": "Content" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "faq",
|
||||||
|
"label": "FAQ",
|
||||||
|
"fields": [
|
||||||
|
{ "name": "category", "type": "string", "label": "Category" },
|
||||||
|
{ "name": "question", "type": "string", "label": "Question" },
|
||||||
|
{ "name": "answer", "type": "string", "label": "Answer" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "settings",
|
||||||
|
"label": "Site Settings",
|
||||||
|
"fields": [
|
||||||
|
{ "name": "siteName", "type": "string", "label": "Site Name" },
|
||||||
|
{ "name": "email", "type": "string", "label": "Contact Email" },
|
||||||
|
{ "name": "phone", "type": "string", "label": "Contact Phone" },
|
||||||
|
{ "name": "address", "type": "string", "label": "Address" },
|
||||||
|
{ "name": "facebook", "type": "string", "label": "Facebook URL" },
|
||||||
|
{ "name": "line", "type": "string", "label": "LINE URL" },
|
||||||
|
{ "name": "linkedin", "type": "string", "label": "LinkedIn URL" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
6
src/live.config.ts
Normal file
6
src/live.config.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { defineLiveCollection } from "astro:content";
|
||||||
|
import { emdashLoader } from "emdash/runtime";
|
||||||
|
|
||||||
|
export const collections = {
|
||||||
|
_emdash: defineLiveCollection({ loader: emdashLoader() }),
|
||||||
|
};
|
||||||
23
src/utils/site-identity.ts
Normal file
23
src/utils/site-identity.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { emdash } from "emdash/astro";
|
||||||
|
import type { CollectionEntry } from "astro:content";
|
||||||
|
|
||||||
|
export async function getSiteSettings() {
|
||||||
|
const context = await emdash(Astro);
|
||||||
|
const settings = context.entries.settings?.[0];
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resolveBlogSiteIdentity(entry: CollectionEntry<"blog">) {
|
||||||
|
return {
|
||||||
|
title: entry.data.title,
|
||||||
|
description: entry.data.excerpt,
|
||||||
|
image: entry.data.image,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getReadingTime(content: string): string {
|
||||||
|
const wordsPerMinute = 200;
|
||||||
|
const words = content.split(/\s+/).length;
|
||||||
|
const minutes = Math.ceil(words / wordsPerMinute);
|
||||||
|
return `${minutes} นาที`;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user