Configure API to send website updates on change
This commit is contained in:
parent
97d47b339a
commit
847666bfc8
@ -2,15 +2,34 @@
|
|||||||
|
|
||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import Tiptap from '../../../components/Tiptap'
|
import { AbstractApi } from '@/app/api/abstract-api';
|
||||||
|
import { Website, WebsiteSerializer } from '@/app/lib/website';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import Tiptap from '../../../components/Tiptap';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
|
|
||||||
|
const [website, setWebsite] = useState<Website>()
|
||||||
|
const api = new AbstractApi<Website>();
|
||||||
|
const serializer = new WebsiteSerializer();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
api.get(serializer, undefined, (loadedWebsite) => {
|
||||||
|
setWebsite(loadedWebsite);
|
||||||
|
console.log('Website loaded:', loadedWebsite);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const updateWebsite = (newContent: string) => {
|
||||||
|
api.update(serializer, new Website('', newContent), () => { });
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="border rounded-lg p-4">
|
<div className="border rounded-lg p-4">
|
||||||
<Tiptap
|
<Tiptap
|
||||||
content="<p>Hello World! 🌎️</p>"
|
key={website?.content ?? 'empty'}
|
||||||
onUpdate={(newContent) => console.log(newContent)}
|
content={website?.content || ''}
|
||||||
|
onUpdate={updateWebsite}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -6,6 +6,7 @@ import { getCsrfToken, getSlug } from '@/app/lib/utils';
|
|||||||
export interface Api<T extends Entity> {
|
export interface Api<T extends Entity> {
|
||||||
getAll(serializable: Serializable<T>, callback: (objets: T[]) => void): void;
|
getAll(serializable: Serializable<T>, callback: (objets: T[]) => void): void;
|
||||||
get(serializable: Serializable<T>, id: string, callback: (object: T) => void): void;
|
get(serializable: Serializable<T>, id: string, callback: (object: T) => void): void;
|
||||||
|
getSingleton(serializable: Serializable<T>, callback: (object: T) => void): void;
|
||||||
create(serializable: Serializable<T>, object: T, callback: (object: T) => void): void;
|
create(serializable: Serializable<T>, object: T, callback: (object: T) => void): void;
|
||||||
update(serializable: Serializable<T>, object: T, callback: () => void): void;
|
update(serializable: Serializable<T>, object: T, callback: () => void): void;
|
||||||
destroy(serializable: Serializable<T>, object: T, callback: () => void): void;
|
destroy(serializable: Serializable<T>, object: T, callback: () => void): void;
|
||||||
@ -30,8 +31,9 @@ export class AbstractApi<T extends Entity> implements Api<T> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get(serializable: Serializable<T>, id: string, callback: (object: T) => void): void {
|
get(serializable: Serializable<T>, id: (string | undefined), callback: (object: T) => void): void {
|
||||||
fetch(`/api/${getSlug()}/${serializable.apiPath()}/${id}`)
|
const endpoint = id ? `/api/${getSlug()}/${serializable.apiPath()}/${id}` : `/api/${getSlug()}/${serializable.apiPath()}`;
|
||||||
|
fetch(endpoint)
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
callback(serializable.fromJson(data));
|
callback(serializable.fromJson(data));
|
||||||
@ -41,7 +43,9 @@ export class AbstractApi<T extends Entity> implements Api<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update(serializable: Serializable<T>, object: T, callback: () => void): void {
|
update(serializable: Serializable<T>, object: T, callback: () => void): void {
|
||||||
fetch(`/api/${getSlug()}/${serializable.apiPath()}/${object.id}`, {
|
const endpoint = object.id ? `/api/${getSlug()}/${serializable.apiPath()}/${object.id}` : `/api/${getSlug()}/${serializable.apiPath()}`;
|
||||||
|
|
||||||
|
fetch(endpoint, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
body: serializable.toJson(object),
|
body: serializable.toJson(object),
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -13,6 +13,7 @@ const Tiptap = ({ content, onUpdate }: { content: string, onUpdate: (newContent:
|
|||||||
onUpdate({ editor }) {
|
onUpdate({ editor }) {
|
||||||
onUpdate(editor.getHTML());
|
onUpdate(editor.getHTML());
|
||||||
},
|
},
|
||||||
|
immediatelyRender: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
return <EditorContent editor={editor} />
|
return <EditorContent editor={editor} />
|
||||||
|
30
app/lib/website.tsx
Normal file
30
app/lib/website.tsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/* Copyright (C) 2024-2025 LibreWeddingPlanner contributors*/
|
||||||
|
|
||||||
|
import { Serializable } from "../api/abstract-api";
|
||||||
|
import { Entity } from "./definitions";
|
||||||
|
|
||||||
|
|
||||||
|
export class Website implements Entity {
|
||||||
|
id?: string;
|
||||||
|
content?: string;
|
||||||
|
|
||||||
|
constructor(id: string, content: string) {
|
||||||
|
this.id = id;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class WebsiteSerializer implements Serializable<Website> {
|
||||||
|
fromJson(data: any): Website {
|
||||||
|
return new Website("", data.content);
|
||||||
|
}
|
||||||
|
|
||||||
|
toJson(website: Website): string {
|
||||||
|
return JSON.stringify({ website: { content: website.content } });
|
||||||
|
}
|
||||||
|
|
||||||
|
apiPath(): string {
|
||||||
|
return 'website';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user