From ba83a6a0258e15cf800b18ec8a501898efdd2598 Mon Sep 17 00:00:00 2001 From: Ardeman Date: Mon, 10 Mar 2025 13:37:50 +0800 Subject: [PATCH] fix: update InputFile component to conditionally reset uploaded file state based on upload status --- app/components/text-editor/editor-menubar.tsx | 520 +++++++++--------- app/components/ui/input-file.tsx | 5 +- 2 files changed, 269 insertions(+), 256 deletions(-) diff --git a/app/components/text-editor/editor-menubar.tsx b/app/components/text-editor/editor-menubar.tsx index 8e3c31b..8a5c612 100644 --- a/app/components/text-editor/editor-menubar.tsx +++ b/app/components/text-editor/editor-menubar.tsx @@ -1,3 +1,4 @@ +import { Input } from '@headlessui/react' import { ArrowUturnLeftIcon, ArrowUturnRightIcon, @@ -6,6 +7,7 @@ import { Bars3Icon, Bars4Icon, BoldIcon, + CloudArrowUpIcon, CodeBracketIcon, DocumentTextIcon, H1Icon, @@ -27,9 +29,12 @@ import { useState, useRef, useCallback, + useEffect, } from 'react' import { HexColorInput, HexColorPicker } from 'react-colorful' +import { Button } from '~/components/ui/button' +import { useAdminContext } from '~/contexts/admin' import { useClickOutside } from '~/hooks/use-click-outside' import { isHexCompatible, rgbToHex } from '~/utils/color' @@ -49,10 +54,27 @@ export const EditorMenuBar = (properties: TProperties) => { // category, disabled = false, } = properties - // const [isOpenImage, setIsOpenImage] = useState(false) + const { setIsUploadOpen, uploadedFile, setUploadedFile } = useAdminContext() + const [isOpenImage, setIsOpenImage] = useState(false) + const [imageUrl, setImageUrl] = useState('') const [isOpenColor, setIsOpenColor] = useState(false) const popover = useRef(null) - const close = useCallback(() => setIsOpenColor(false), []) + const close = useCallback(() => { + setIsOpenColor(false) + setIsOpenImage(false) + if (imageUrl) { + addImage(imageUrl) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + useEffect(() => { + if (uploadedFile) { + addImage(uploadedFile) + setUploadedFile(undefined) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [uploadedFile]) useClickOutside(popover, close) @@ -96,167 +118,150 @@ export const EditorMenuBar = (properties: TProperties) => { } } - const uploadEnabled = false - const toggleUpload = () => { - if (uploadEnabled) { - // setIsOpenImage(true) - } else { - const urlImage = globalThis.prompt('URL') - if (urlImage) { - addImage(urlImage) - } - } - } - return ( - <> -
-
-
+
+
+
+ editor.chain().focus().toggleBold().run()} + disabled={ + disabled || !editor.can().chain().focus().toggleBold().run() + } + isActive={editor.isActive('bold')} + title="Bold" + > + + + editor.chain().focus().toggleItalic().run()} + disabled={ + disabled || !editor.can().chain().focus().toggleItalic().run() + } + isActive={editor.isActive('italic')} + title="Italic" + > + + + editor.chain().focus().toggleStrike().run()} + disabled={ + disabled || !editor.can().chain().focus().toggleStrike().run() + } + isActive={editor.isActive('strike')} + title="Strike" + > + + +
editor.chain().focus().toggleBold().run()} - disabled={ - disabled || !editor.can().chain().focus().toggleBold().run() - } - isActive={editor.isActive('bold')} - title="Bold" + onClick={() => setIsOpenColor(true)} + title="Text Color" + style={{ + color: rgbColor, + }} + isActive={true} + disabled={disabled} > - + - editor.chain().focus().toggleItalic().run()} - disabled={ - disabled || !editor.can().chain().focus().toggleItalic().run() - } - isActive={editor.isActive('italic')} - title="Italic" - > - - - editor.chain().focus().toggleStrike().run()} - disabled={ - disabled || !editor.can().chain().focus().toggleStrike().run() - } - isActive={editor.isActive('strike')} - title="Strike" - > - - -
- setIsOpenColor(true)} - title="Text Color" - style={{ - color: rgbColor, - }} - isActive={true} - disabled={disabled} + {isOpenColor && ( +
- - - {isOpenColor && ( -
- +
+ -
- -
- )} -
- editor.chain().focus().setTextAlign('left').run()} - disabled={ - disabled || - !editor.can().chain().focus().setTextAlign('left').run() - } - isActive={editor.isActive({ textAlign: 'left' })} - title="Align Left" - > - - - - editor.chain().focus().setTextAlign('center').run() - } - disabled={ - disabled || - !editor.can().chain().focus().setTextAlign('center').run() - } - isActive={editor.isActive({ textAlign: 'center' })} - title="Align Center" - > - - - editor.chain().focus().setTextAlign('right').run()} - disabled={ - disabled || - !editor.can().chain().focus().setTextAlign('right').run() - } - isActive={editor.isActive({ textAlign: 'right' })} - title="Align Right" - > - - - - editor.chain().focus().setTextAlign('justify').run() - } - disabled={ - disabled || - !editor.can().chain().focus().setTextAlign('justify').run() - } - isActive={editor.isActive({ textAlign: 'justify' })} - title="Align Justify" - > - - +
+ )}
-
- - editor.chain().focus().toggleHeading({ level: 1 }).run() - } - isActive={editor.isActive('heading', { level: 1 })} - title="Heading 1" - disabled={disabled} - > - - - - editor.chain().focus().toggleHeading({ level: 2 }).run() - } - isActive={editor.isActive('heading', { level: 2 })} - title="Heading 2" - disabled={disabled} - > - - - - editor.chain().focus().toggleHeading({ level: 3 }).run() - } - isActive={editor.isActive('heading', { level: 3 })} - title="Heading 3" - disabled={disabled} - > - - - {/* editor.chain().focus().setTextAlign('left').run()} + disabled={ + disabled || + !editor.can().chain().focus().setTextAlign('left').run() + } + isActive={editor.isActive({ textAlign: 'left' })} + title="Align Left" + > + + + editor.chain().focus().setTextAlign('center').run()} + disabled={ + disabled || + !editor.can().chain().focus().setTextAlign('center').run() + } + isActive={editor.isActive({ textAlign: 'center' })} + title="Align Center" + > + + + editor.chain().focus().setTextAlign('right').run()} + disabled={ + disabled || + !editor.can().chain().focus().setTextAlign('right').run() + } + isActive={editor.isActive({ textAlign: 'right' })} + title="Align Right" + > + + + editor.chain().focus().setTextAlign('justify').run()} + disabled={ + disabled || + !editor.can().chain().focus().setTextAlign('justify').run() + } + isActive={editor.isActive({ textAlign: 'justify' })} + title="Align Justify" + > + + +
+
+ + editor.chain().focus().toggleHeading({ level: 1 }).run() + } + isActive={editor.isActive('heading', { level: 1 })} + title="Heading 1" + disabled={disabled} + > + + + + editor.chain().focus().toggleHeading({ level: 2 }).run() + } + isActive={editor.isActive('heading', { level: 2 })} + title="Heading 2" + disabled={disabled} + > + + + + editor.chain().focus().toggleHeading({ level: 3 }).run() + } + isActive={editor.isActive('heading', { level: 3 })} + title="Heading 3" + disabled={disabled} + > + + + {/* editor.chain().focus().setParagraph().run()} isActive={editor.isActive('paragraph')} title="Paragraph" @@ -264,32 +269,32 @@ export const EditorMenuBar = (properties: TProperties) => { > */} - editor.chain().focus().toggleBulletList().run()} - isActive={editor.isActive('bulletList')} - title="Bullet List" - disabled={disabled} - > - - - editor.chain().focus().toggleOrderedList().run()} - isActive={editor.isActive('orderedList')} - title="Ordered List" - disabled={disabled} - > - - - editor.chain().focus().toggleCodeBlock().run()} - isActive={editor.isActive('codeBlock')} - title="Code Block" - disabled={disabled} - > - - -
- {/*
+ editor.chain().focus().toggleBulletList().run()} + isActive={editor.isActive('bulletList')} + title="Bullet List" + disabled={disabled} + > + + + editor.chain().focus().toggleOrderedList().run()} + isActive={editor.isActive('orderedList')} + title="Ordered List" + disabled={disabled} + > + + + editor.chain().focus().toggleCodeBlock().run()} + isActive={editor.isActive('codeBlock')} + title="Code Block" + disabled={disabled} + > + + +
+ {/*
editor.chain().focus().toggleBlockquote().run()} isActive={editor.isActive('blockquote')} @@ -306,7 +311,7 @@ export const EditorMenuBar = (properties: TProperties) => {
*/} - {/*
+ {/*
editor.chain().focus().setHardBreak().run()} title="Hard Break" @@ -325,89 +330,96 @@ export const EditorMenuBar = (properties: TProperties) => {
*/} -
+
+
toggleUpload()} + onClick={() => setIsOpenImage(true)} title="Insert Image" disabled={disabled} > - setLink()} - disabled={ - disabled || - !editor - .can() - .chain() - .focus() - .extendMarkRange('link') - .setLink({ href: '' }) - .run() - } - isActive={editor.isActive('link')} - title="Set Link" - > - - - editor.chain().focus().unsetLink().run()} - disabled={disabled || !editor.isActive('link')} - title="Unset Link" - > - - -
-
- editor.chain().focus().undo().run()} - disabled={disabled || !editor.can().chain().focus().undo().run()} - title="Undo" - > - - - editor.chain().focus().redo().run()} - disabled={disabled || !editor.can().chain().focus().redo().run()} - title="Redo" - > - - + {isOpenImage && ( +
+
+ { + setImageUrl(event.target.value) + }} + className="z-10 flex h-[42px] w-full rounded-lg border-0 bg-white p-2 pr-8 text-sm shadow read-only:bg-gray-100 focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none focus-visible:outline-0 disabled:bg-gray-100" + /> + +
+
+ )}
+ setLink()} + disabled={ + disabled || + !editor + .can() + .chain() + .focus() + .extendMarkRange('link') + .setLink({ href: '' }) + .run() + } + isActive={editor.isActive('link')} + title="Set Link" + > + + + editor.chain().focus().unsetLink().run()} + disabled={disabled || !editor.isActive('link')} + title="Unset Link" + > + +
-
-
- setIsPlainHTML(true)} - title="Switch to Plain Text" - > - - -
+
+ editor.chain().focus().undo().run()} + disabled={disabled || !editor.can().chain().focus().undo().run()} + title="Undo" + > + + + editor.chain().focus().redo().run()} + disabled={disabled || !editor.can().chain().focus().redo().run()} + title="Redo" + > + +
- - {/* - setIsOpenImage(false), - onSave: (file) => { - addImage(file) - setIsOpenImage(false) - }, - category: category, - maxFileSize: 300, - selectedFile: '', - }} - > - - - */} - +
+
+ setIsPlainHTML(true)} + title="Switch to Plain Text" + > + + +
+
+
) } diff --git a/app/components/ui/input-file.tsx b/app/components/ui/input-file.tsx index c43319e..dc85361 100644 --- a/app/components/ui/input-file.tsx +++ b/app/components/ui/input-file.tsx @@ -42,7 +42,8 @@ export const InputFile = >( labelClassName, ...restProperties } = properties - const { setIsUploadOpen, uploadedFile, setUploadedFile } = useAdminContext() + const { setIsUploadOpen, uploadedFile, setUploadedFile, isUploadOpen } = + useAdminContext() const { register, @@ -53,7 +54,7 @@ export const InputFile = >( const error: FieldError = get(errors, name) useEffect(() => { - if (uploadedFile) { + if (uploadedFile && isUploadOpen === name) { setValue(name as string, uploadedFile) setUploadedFile(undefined) }