All checks were successful
		
		
	
	Check usage of free licenses / build-static-assets (pull_request) Successful in 1m39s
				
			Add copyright notice / copyright_notice (pull_request) Successful in 2m15s
				
			Build Nginx-based docker image / build-static-assets (push) Successful in 6m45s
				
			Playwright Tests / test (pull_request) Successful in 6m46s
				
			
		
			
				
	
	
		
			65 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			65 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| /* Copyright (C) 2024-2025 LibreWeddingPlanner contributors*/
 | |
| 
 | |
| 'use client'
 | |
| 
 | |
| import { AbstractApi } from '@/app/api/abstract-api';
 | |
| import { getSlug } from '@/app/lib/utils';
 | |
| import { Website, WebsiteSerializer } from '@/app/lib/website';
 | |
| import { useEffect, useState } from 'react';
 | |
| import Tiptap from '../../../components/Tiptap';
 | |
| 
 | |
| 
 | |
| export default function Page() {
 | |
| 
 | |
|   const [website, setWebsite] = useState<Website>()
 | |
|   const api = new AbstractApi<Website>();
 | |
|   const serializer = new WebsiteSerializer();
 | |
| 
 | |
|   const [slug, setSlug] = useState<string>("default");
 | |
|   useEffect(() => { setSlug(getSlug()) }, []);
 | |
| 
 | |
|   const [iframeKey, setIframeKey] = useState<number>(Math.random());
 | |
| 
 | |
|   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), () => {
 | |
|           setIframeKey(Math.random()); // Change key to force iframe reload
 | |
|         });
 | |
|       }, 500)
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   return (
 | |
|     <div className="flex">
 | |
|       <div className="w-1/2 border rounded-lg p-4">
 | |
|         <Tiptap
 | |
|           key={website?.content ?? 'empty'}
 | |
|           content={website?.content || ''}
 | |
|           onUpdate={updateWebsite}
 | |
|         />
 | |
|       </div>
 | |
|       <div className="w-1/2 border rounded-lg p-4 ml-4">
 | |
|         <iframe
 | |
|           key={iframeKey}
 | |
|           src={`/${slug}/site`}
 | |
|           title="Website Preview"
 | |
|           className="w-full h-[80vh] rounded"
 | |
|         />
 | |
|       </div>
 | |
|     </div>
 | |
|   );
 | |
| } |