import axiosInstance from '../src/axiosSecure'; import dynamic from 'next/dynamic'; import React, { useState, useRef, useEffect, forwardRef, useImperativeHandle } from 'react'; import 'react-quill/dist/quill.snow.css'; //!!! working //const ReactQuill = dynamic(() => import('react-quill'), { ssr: false }); // const ImageResize = dynamic(() => import('quill-image-resize'), { ssr: false }); const ReactQuill = dynamic( async () => { const { default: RQ } = await import('react-quill'); // const { default: ImageUploader } = await import('./ImageUploader/ImageUploader'); const { default: ImageResize } = await import('quill-image-resize'); RQ.Quill.register('modules/imageResize', ImageResize); return RQ; }, { ssr: false, }, ); // import { // Dispatch, // LegacyRef, // memo, // SetStateAction, // useMemo, // } from 'react'; // interface IQuillEditor extends ReactQuillProps { // forwardedRef: LegacyRef; // } // const QuillNoSSRWrapper = dynamic( // async () => { // const { default: RQ } = await import('react-quill'); // // eslint-disable-next-line react/display-name // return function editor({ forwardedRef, ...props }: IQuillEditor) { // return ; // }; // }, // { ssr: false } // ); const formats = [ 'header', 'bold', 'italic', 'underline', 'strike', 'blockquote', 'list', 'bullet', 'indent', 'link', 'image', 'code', 'color', 'background', 'code-block', 'align', ]; interface OnChangeHandler { (e: any): void; } type Props = { value: string; placeholder: string; onChange: OnChangeHandler; prefix: string; }; const TextEditor: React.FC = forwardRef((props, ref) => { const { value, placeholder, onChange, prefix } = props; const quillRef = useRef(ref); const handleOnChange = (e) => { if (quillRef.current) { const delta = quillRef.current.getEditor().getContents(); const html = quillRef.current.getEditor().getHTML(); onChange(html); } }; useImperativeHandle(ref, () => ({ getQuill: () => quillRef.current, })); const imageHandler = async () => { const input = document.createElement('input'); input.setAttribute('type', 'file'); input.setAttribute('accept', 'image/*'); input.click(); input.onchange = async () => { const uploadPromises = Array.from(input.files).map(async (item) => { const formData = new FormData(); formData.append('image', item); formData.append('prefix', prefix); try { const response = await axiosInstance.post('upload', formData); const imageUrl = response.data.imageUrl; if (quillRef.current) { // const editor = quillRef.current.getEditor(); const editor = quillRef.current.getQuill(); // Adjust based on your useImperativeHandle setup const range = editor.getSelection(true); editor.insertEmbed(range.index, 'image', imageUrl); return range.index + 1; } } catch (error) { console.error('Error uploading image:', error); } }); const cursorPositions = await Promise.all(uploadPromises); const lastCursorPosition = cursorPositions.pop(); if (lastCursorPosition !== undefined && quillRef.current) { const editor = quillRef.current.getEditor(); editor.setSelection(lastCursorPosition); } }; }; const modules = React.useMemo( () => ({ toolbar: { container: [ // [{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown [{ header: [1, 2, 3, 4, 5, 6, false] }], ['bold', 'italic', 'underline', 'strike', 'blockquote', 'code-block'], [{ list: 'ordered' }, { list: 'bullet' }, { indent: '-1' }, { indent: '+1' }], ['link', 'image'], [{ color: [] }, { background: [] }, { align: [] }], ['clean'], ], // container: [ // [{ 'font': [] }], // Dropdown to select font // [{ 'size': ['small', false, 'large', 'huge'] }], // Dropdown to select font size // [{ 'header': [1, 2, 3, 4, 5, 6, false] }], // ['bold', 'italic', 'underline', 'strike'], // toggled buttons // [{ 'script': 'sub' }, { 'script': 'super' }], // superscript/subscript // ['blockquote', 'code-block'], // [{ 'list': 'ordered' }, { 'list': 'bullet' }], // [{ 'indent': '-1' }, { 'indent': '+1' }], // indent/outdent // [{ 'direction': 'rtl' }], // text direction // [{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme // [{ 'align': [] }], // ['link', 'image', 'video'], // link and image, video // ['clean'] // remove formatting button // ], // we can't fix this so temporary disable it // handlers: { // image: imageHandler, // }, }, imageResize: true }), [imageHandler], ); //test if we ever get the ref! useEffect(() => { if (quillRef.current) { console.log('quillRef.current: ', quillRef.current); // You can now access the Quill instance directly via quillRef.current.getEditor() // This is useful for any setup or instance-specific adjustments you might need } }, []); return ( <> ); // return ; }); export default TextEditor;