Update admin theme/layout and refresh README details.

Align the project baseline with the latest admin interface styling and layout structure while documenting setup and usage updates in README.
This commit is contained in:
vlad
2026-07-14 17:12:28 +03:00
commit 86cc3fa541
278 changed files with 19416 additions and 0 deletions
@@ -0,0 +1,53 @@
import { describe, expect, it, vi } from "vitest";
import {
createContentPage,
deleteContentPage,
getAdminPages,
getPageBySlug,
updateContentPage
} from "./contentApi";
vi.mock("@shared/api/client", () => ({
apiClient: {
get: vi.fn(async (url: string) => {
if (url === "/api/v1/content/pages/manage/all") {
return { data: { data: [{ id: "1", slug: "about", title: "About", body: "", status: "published" }] } };
}
return { data: { slug: "about", title: "About" } };
}),
post: vi.fn(async () => ({ data: { id: "2", slug: "new", title: "New", body: "", status: "draft" } })),
patch: vi.fn(async () => ({ data: { id: "1", slug: "about", title: "Updated", body: "", status: "published" } })),
delete: vi.fn(async () => ({ data: {} }))
}
}));
describe("contentApi", () => {
it("loads page by slug", async () => {
const data = await getPageBySlug("about");
expect(data.slug).toBe("about");
});
it("loads admin pages", async () => {
const pages = await getAdminPages();
expect(pages[0].slug).toBe("about");
});
it("creates content page", async () => {
const page = await createContentPage({
slug: "new",
title: "New",
body: "<p>x</p>",
status: "draft"
});
expect(page.slug).toBe("new");
});
it("updates content page", async () => {
const page = await updateContentPage("1", { title: "Updated" });
expect(page.title).toBe("Updated");
});
it("deletes content page", async () => {
await expect(deleteContentPage("1")).resolves.toBeUndefined();
});
});
@@ -0,0 +1,41 @@
import { apiClient } from "@shared/api/client";
export interface ContentPage {
id: string;
slug: string;
title: string;
body: string;
status: string;
}
export async function getPageBySlug(slug: string) {
const { data } = await apiClient.get(`/api/v1/content/pages/${slug}`);
return data;
}
export async function getAdminPages(): Promise<ContentPage[]> {
const { data } = await apiClient.get<{ data: ContentPage[] }>("/api/v1/content/pages/manage/all");
return data.data;
}
export async function createContentPage(payload: {
slug: string;
title: string;
body: string;
status: string;
}): Promise<ContentPage> {
const { data } = await apiClient.post<ContentPage>("/api/v1/content/pages", payload);
return data;
}
export async function updateContentPage(
pageId: string,
payload: { title?: string; body?: string; status?: string }
): Promise<ContentPage> {
const { data } = await apiClient.patch<ContentPage>(`/api/v1/content/pages/${pageId}`, payload);
return data;
}
export async function deleteContentPage(pageId: string): Promise<void> {
await apiClient.delete(`/api/v1/content/pages/${pageId}`);
}