Compare commits

..

No commits in common. "0b8a444b39440241e4449eec7eb525e45ca56a92" and "97d47b339aa67a40b9c9c7369087eaafbbd198f1" have entirely different histories.

4 changed files with 6 additions and 70 deletions

View File

@ -2,44 +2,15 @@
'use client'
import { AbstractApi } from '@/app/api/abstract-api';
import { Website, WebsiteSerializer } from '@/app/lib/website';
import { useEffect, useState } from 'react';
import Tiptap from '../../../components/Tiptap';
import Tiptap from '../../../components/Tiptap'
export default function Page() {
const [website, setWebsite] = useState<Website>()
const api = new AbstractApi<Website>();
const serializer = new WebsiteSerializer();
const [timeoutId, setTimeoutId] = useState<NodeJS.Timeout | null>(null);
useEffect(() => {
api.get(serializer, undefined, (loadedWebsite) => {
setWebsite(loadedWebsite);
});
}, []);
const updateWebsite = (newContent: string) => {
// Debounce API update: send after 500ms of no further changes
if (timeoutId) {
clearTimeout(timeoutId);
}
setTimeoutId(
setTimeout(() => {
api.update(serializer, new Website('', newContent), () => { });
}, 500)
);
}
return (
<div className="border rounded-lg p-4">
<Tiptap
key={website?.content ?? 'empty'}
content={website?.content || ''}
onUpdate={updateWebsite}
content="<p>Hello World! 🌎️</p>"
onUpdate={(newContent) => console.log(newContent)}
/>
</div>
);

View File

@ -6,7 +6,6 @@ import { getCsrfToken, getSlug } from '@/app/lib/utils';
export interface Api<T extends Entity> {
getAll(serializable: Serializable<T>, callback: (objets: 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;
update(serializable: Serializable<T>, object: T, callback: () => void): void;
destroy(serializable: Serializable<T>, object: T, callback: () => void): void;
@ -31,9 +30,8 @@ export class AbstractApi<T extends Entity> implements Api<T> {
});
}
get(serializable: Serializable<T>, id: (string | undefined), callback: (object: T) => void): void {
const endpoint = id ? `/api/${getSlug()}/${serializable.apiPath()}/${id}` : `/api/${getSlug()}/${serializable.apiPath()}`;
fetch(endpoint)
get(serializable: Serializable<T>, id: string, callback: (object: T) => void): void {
fetch(`/api/${getSlug()}/${serializable.apiPath()}/${id}`)
.then((response) => response.json())
.then((data) => {
callback(serializable.fromJson(data));
@ -43,9 +41,7 @@ export class AbstractApi<T extends Entity> implements Api<T> {
}
update(serializable: Serializable<T>, object: T, callback: () => void): void {
const endpoint = object.id ? `/api/${getSlug()}/${serializable.apiPath()}/${object.id}` : `/api/${getSlug()}/${serializable.apiPath()}`;
fetch(endpoint, {
fetch(`/api/${getSlug()}/${serializable.apiPath()}/${object.id}`, {
method: 'PUT',
body: serializable.toJson(object),
headers: {

View File

@ -13,7 +13,6 @@ const Tiptap = ({ content, onUpdate }: { content: string, onUpdate: (newContent:
onUpdate({ editor }) {
onUpdate(editor.getHTML());
},
immediatelyRender: false,
})
return <EditorContent editor={editor} />

View File

@ -1,30 +0,0 @@
/* 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';
}
}