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"
|
||||
},
|
||||
"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,
|
||||
"lintCommand": null,
|
||||
"devCommand": "npm run dev",
|
||||
@@ -207,6 +207,12 @@
|
||||
"lastAccessed": 1777990670077,
|
||||
"type": "file"
|
||||
},
|
||||
{
|
||||
"path": "src/layouts/Base.astro",
|
||||
"accessCount": 4,
|
||||
"lastAccessed": 1778036775836,
|
||||
"type": "file"
|
||||
},
|
||||
{
|
||||
"path": "src/styles/global.css",
|
||||
"accessCount": 3,
|
||||
@@ -219,6 +225,12 @@
|
||||
"lastAccessed": 1777995178143,
|
||||
"type": "directory"
|
||||
},
|
||||
{
|
||||
"path": "astro.config.mjs",
|
||||
"accessCount": 2,
|
||||
"lastAccessed": 1778036187649,
|
||||
"type": "file"
|
||||
},
|
||||
{
|
||||
"path": "src/pages",
|
||||
"accessCount": 1,
|
||||
@@ -230,6 +242,24 @@
|
||||
"accessCount": 1,
|
||||
"lastAccessed": 1778035760907,
|
||||
"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": []
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"tool_name": "Bash",
|
||||
"tool_input_preview": "{\"command\":\"npm run build 2>&1\",\"timeout\":120000,\"description\":\"Build Astro site to check for errors\"}",
|
||||
"error": "Exit code 1",
|
||||
"timestamp": "2026-05-05T13:17:02.070Z",
|
||||
"tool_name": "Write",
|
||||
"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": "EACCES: permission denied, mkdir '/Users/kunthawatgleethong'",
|
||||
"timestamp": "2026-05-06T03:03:02.581Z",
|
||||
"retry_count": 1
|
||||
}
|
||||
@@ -1,5 +1,20 @@
|
||||
// @ts-check
|
||||
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"
|
||||
},
|
||||
"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