From 0459c9536c4dd6a8b412a301f4069acc3fa167fb Mon Sep 17 00:00:00 2001 From: Michael Freno Date: Fri, 19 Dec 2025 12:54:03 -0500 Subject: [PATCH] migrated editing client --- bun.lockb | Bin 328472 -> 356311 bytes package.json | 10 + src/components/blog/AddAttachmentSection.tsx | 177 +++++++ src/components/blog/Dropzone.tsx | 115 +++++ src/components/blog/TagMaker.tsx | 58 +++ src/components/blog/TextEditor.tsx | 488 +++++++++++++++++++ src/routes/blog/create/index.tsx | 302 ++++++++---- src/routes/blog/edit/[id]/index.tsx | 327 +++++++++---- 8 files changed, 1285 insertions(+), 192 deletions(-) create mode 100644 src/components/blog/AddAttachmentSection.tsx create mode 100644 src/components/blog/Dropzone.tsx create mode 100644 src/components/blog/TagMaker.tsx create mode 100644 src/components/blog/TextEditor.tsx diff --git a/bun.lockb b/bun.lockb index ec0da28800673b9942be2bab7a2cb071c35ed0f5..a4859bf935411ed7843133aedb3fd411b30fe0ca 100755 GIT binary patch delta 74882 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[]); + const [imageHolder, setImageHolder] = createSignal([]); + const [newImageHolder, setNewImageHolder] = createSignal([]); + const [newImageHolderKeys, setNewImageHolderKeys] = createSignal( + [] + ); + + createEffect(() => { + if (props.existingAttachments) { + const imgStringArr = props.existingAttachments.split(","); + setImageHolder(imgStringArr); + } + }); + + const handleImageDrop = async (acceptedFiles: File[]) => { + if (props.postTitle) { + for (const file of acceptedFiles) { + setImages((prev) => [...prev, file]); + + try { + const key = await AddImageToS3(file, props.postTitle, props.type); + if (key) { + setNewImageHolderKeys((prev) => [...prev, key]); + + const reader = new FileReader(); + reader.onload = () => { + const str = reader.result; + if (str) { + setNewImageHolder((prev) => [...prev, str as string]); + } + }; + reader.readAsDataURL(file); + } + } catch (err) { + console.error("Failed to upload image:", err); + } + } + } + }; + + const removeImage = async (index: number, key: string) => { + if (props.postId && props.existingAttachments) { + const imgStringArr = props.existingAttachments.split(","); + const newString = imgStringArr.filter((str) => str !== key).join(","); + + try { + await fetch("/api/trpc/misc.deleteImage", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + key, + newAttachmentString: newString, + type: props.type, + id: props.postId + }) + }); + + setImageHolder((prev) => prev.filter((_, i) => i !== index)); + } catch (err) { + console.error("Failed to delete image:", err); + } + } + }; + + const removeNewImage = async (index: number, key: string) => { + setImages((prev) => prev.filter((_, i) => i !== index)); + setNewImageHolder((prev) => prev.filter((_, i) => i !== index)); + + try { + await fetch("/api/trpc/misc.simpleDeleteImage", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ key }) + }); + } catch (err) { + console.error("Failed to delete image:", err); + } + }; + + const copyToClipboard = async (key: string) => { + try { + const bucketString = import.meta.env.VITE_AWS_BUCKET_STRING || ""; + await navigator.clipboard.writeText(bucketString + key); + console.log("Text copied to clipboard"); + } catch (err) { + console.error("Failed to copy text:", err); + } + }; + + return ( + + Add title to add attachments + + } + > +
Attachments
+
+ +
+
+ + {(key, index) => ( +
+ + attachment +
+ )} +
+
+ + {(img, index) => ( +
+ + +
+ )} +
+
+ + ); +} diff --git a/src/components/blog/Dropzone.tsx b/src/components/blog/Dropzone.tsx new file mode 100644 index 0000000..c3211ac --- /dev/null +++ b/src/components/blog/Dropzone.tsx @@ -0,0 +1,115 @@ +import { Show } from "solid-js"; + +export interface DropzoneProps { + onDrop: (files: File[]) => void; + accept?: string; + fileHolder?: string | ArrayBuffer | null; + preSet?: string | null; +} + +export default function Dropzone(props: DropzoneProps) { + let inputRef: HTMLInputElement | undefined; + + const handleFileChange = (e: Event) => { + const target = e.target as HTMLInputElement; + const files = target.files; + if (files && files.length > 0) { + props.onDrop(Array.from(files)); + } + }; + + const handleDrop = (e: DragEvent) => { + e.preventDefault(); + const files = e.dataTransfer?.files; + if (files && files.length > 0) { + props.onDrop(Array.from(files)); + } + }; + + const handleDragOver = (e: DragEvent) => { + e.preventDefault(); + }; + + return ( +
inputRef?.click()} + > + +
+ ); +} diff --git a/src/components/blog/TagMaker.tsx b/src/components/blog/TagMaker.tsx new file mode 100644 index 0000000..829d20e --- /dev/null +++ b/src/components/blog/TagMaker.tsx @@ -0,0 +1,58 @@ +import { For } from "solid-js"; +import InfoIcon from "~/components/icons/InfoIcon"; +import Xmark from "~/components/icons/Xmark"; + +export interface TagMakerProps { + tagInputValue: string; + tagHandler: (input: string) => void; + tags: string[]; + deleteTag: (idx: number) => void; +} + +export default function TagMaker(props: TagMakerProps) { + return ( +
+
+
+
+ +
+
+
start with # end with a space
+
+
+
+
+
+ props.tagHandler(e.currentTarget.value)} + name="message" + placeholder=" " + class="underlinedInput w-full bg-transparent select-text" + /> + + +
+
+
+ + {(tag, idx) => ( +
+
+ {tag} +
+ +
+ )} +
+
+
+ ); +} diff --git a/src/components/blog/TextEditor.tsx b/src/components/blog/TextEditor.tsx new file mode 100644 index 0000000..77df348 --- /dev/null +++ b/src/components/blog/TextEditor.tsx @@ -0,0 +1,488 @@ +import { Show } from "solid-js"; +import { createTiptapEditor, useEditorHTML } from "solid-tiptap"; +import StarterKit from "@tiptap/starter-kit"; +import Link from "@tiptap/extension-link"; +import CodeBlockLowlight from "@tiptap/extension-code-block-lowlight"; +import Image from "@tiptap/extension-image"; +import { Node } from "@tiptap/core"; +import { createLowlight, common } from "lowlight"; +import css from "highlight.js/lib/languages/css"; +import js from "highlight.js/lib/languages/javascript"; +import ts from "highlight.js/lib/languages/typescript"; +import ocaml from "highlight.js/lib/languages/ocaml"; +import rust from "highlight.js/lib/languages/rust"; + +// Create lowlight instance with common languages +const lowlight = createLowlight(common); + +// Register additional languages +lowlight.register("css", css); +lowlight.register("js", js); +lowlight.register("ts", ts); +lowlight.register("ocaml", ocaml); +lowlight.register("rust", rust); + +// IFrame extension +interface IframeOptions { + allowFullscreen: boolean; + HTMLAttributes: { + [key: string]: any; + }; +} + +declare module "@tiptap/core" { + interface Commands { + iframe: { + setIframe: (options: { src: string }) => ReturnType; + }; + } +} + +const IframeEmbed = Node.create({ + name: "iframe", + group: "block", + atom: true, + + addOptions() { + return { + allowFullscreen: true, + HTMLAttributes: { + class: "iframe-wrapper" + } + }; + }, + + addAttributes() { + return { + src: { + default: null + }, + frameborder: { + default: 0 + }, + allowfullscreen: { + default: this.options.allowFullscreen, + parseHTML: () => this.options.allowFullscreen + } + }; + }, + + parseHTML() { + return [ + { + tag: "iframe" + } + ]; + }, + + renderHTML({ HTMLAttributes }) { + return ["div", this.options.HTMLAttributes, ["iframe", HTMLAttributes]]; + }, + + addCommands() { + return { + setIframe: + (options: { src: string }) => + ({ tr, dispatch }) => { + const { selection } = tr; + const node = this.type.create(options); + + if (dispatch) { + tr.replaceRangeWith(selection.from, selection.to, node); + } + + return true; + } + }; + } +}); + +export interface TextEditorProps { + updateContent: (content: string) => void; + preSet?: string; +} + +export default function TextEditor(props: TextEditorProps) { + let editorRef!: HTMLDivElement; + + const editor = createTiptapEditor(() => ({ + element: editorRef, + extensions: [ + StarterKit, + CodeBlockLowlight.configure({ lowlight }), + Link.configure({ + openOnClick: true + }), + Image, + IframeEmbed + ], + content: props.preSet || `

Hello! World

`, + onUpdate: ({ editor }) => { + props.updateContent(editor.getHTML()); + } + })); + + const setLink = () => { + const instance = editor(); + if (!instance) return; + + const previousUrl = instance.getAttributes("link").href; + const url = window.prompt("URL", previousUrl); + + if (url === null) return; + + if (url === "") { + instance.chain().focus().extendMarkRange("link").unsetLink().run(); + return; + } + + instance + .chain() + .focus() + .extendMarkRange("link") + .setLink({ href: url }) + .run(); + }; + + const addIframe = () => { + const instance = editor(); + if (!instance) return; + + const url = window.prompt("URL"); + if (url) { + instance.commands.setIframe({ src: url }); + } + }; + + const addImage = () => { + const instance = editor(); + if (!instance) return; + + const url = window.prompt("URL"); + if (url) { + instance.chain().focus().setImage({ src: url }).run(); + } + }; + + return ( +
+ + {(instance) => ( + <> + {/* Bubble Menu - appears when text is selected */} +
+
+
+ + + + + + + + +
+
+
+ + {/* Toolbar - always visible */} +
+ + + +
+ + + +
+ + + +
+ + + + +
+ +
+ + )} +
+ +
+
+ ); +} diff --git a/src/routes/blog/create/index.tsx b/src/routes/blog/create/index.tsx index a4a8e69..9d1a9b9 100644 --- a/src/routes/blog/create/index.tsx +++ b/src/routes/blog/create/index.tsx @@ -1,10 +1,16 @@ -import { Show, createSignal } from "solid-js"; -import { useSearchParams, useNavigate, query } from "@solidjs/router"; +import { Show, createSignal, onCleanup } from "solid-js"; +import { useNavigate, query } from "@solidjs/router"; import { Title } from "@solidjs/meta"; import { createAsync } from "@solidjs/router"; import { getRequestEvent } from "solid-js/web"; import { getPrivilegeLevel, getUserID } from "~/server/utils"; import { api } from "~/lib/api"; +import Dropzone from "~/components/blog/Dropzone"; +import TextEditor from "~/components/blog/TextEditor"; +import TagMaker from "~/components/blog/TagMaker"; +import AddAttachmentSection from "~/components/blog/AddAttachmentSection"; +import XCircle from "~/components/icons/XCircle"; +import AddImageToS3 from "~/lib/s3upload"; const getAuthState = query(async () => { "use server"; @@ -17,19 +23,124 @@ const getAuthState = query(async () => { }, "auth-state"); export default function CreatePost() { - const [searchParams] = useSearchParams(); const navigate = useNavigate(); - const authState = createAsync(() => getAuthState()); const [title, setTitle] = createSignal(""); const [subtitle, setSubtitle] = createSignal(""); const [body, setBody] = createSignal(""); - const [bannerPhoto, setBannerPhoto] = createSignal(""); + const [bannerPhoto, setBannerPhoto] = createSignal(""); + const [bannerImageFile, setBannerImageFile] = createSignal(); + const [bannerImageHolder, setBannerImageHolder] = createSignal< + string | ArrayBuffer | null + >(null); const [published, setPublished] = createSignal(false); const [tags, setTags] = createSignal([]); + const [tagInputValue, setTagInputValue] = createSignal(""); const [loading, setLoading] = createSignal(false); const [error, setError] = createSignal(""); + const [showAutoSaveMessage, setShowAutoSaveMessage] = createSignal(false); + const [hasSaved, setHasSaved] = createSignal(false); + + let autosaveInterval: number | undefined; + + const autoSave = async () => { + const titleVal = title(); + const bodyVal = body(); + + if (titleVal && bodyVal !== "") { + try { + let bannerImageKey = ""; + const bannerFile = bannerImageFile(); + if (bannerFile) { + bannerImageKey = (await AddImageToS3( + bannerFile, + titleVal, + "blog" + )) as string; + } + + const method = hasSaved() ? "PATCH" : "POST"; + + if (method === "POST") { + await api.database.createPost.mutate({ + category: "blog", + title: titleVal.replaceAll(" ", "_"), + subtitle: subtitle() || null, + body: bodyVal || null, + banner_photo: bannerImageKey !== "" ? bannerImageKey : null, + published: published(), + tags: tags().length > 0 ? tags() : null, + author_id: authState()!.userID + }); + } + + setHasSaved(true); + showAutoSaveTrigger(); + } catch (err) { + console.error("Autosave failed:", err); + } + } + }; + + const showAutoSaveTrigger = () => { + setShowAutoSaveMessage(true); + setTimeout(() => { + setShowAutoSaveMessage(false); + }, 5000); + }; + + // Set up autosave interval (2 minutes) + autosaveInterval = setInterval( + () => { + autoSave(); + }, + 2 * 60 * 1000 + ) as unknown as number; + + onCleanup(() => { + if (autosaveInterval) { + clearInterval(autosaveInterval); + } + }); + + const handleBannerImageDrop = (acceptedFiles: File[]) => { + if (acceptedFiles.length > 0) { + const file = acceptedFiles[0]; + setBannerImageFile(file); + const reader = new FileReader(); + reader.onload = () => { + setBannerImageHolder(reader.result); + }; + reader.readAsDataURL(file); + } + }; + + const removeBannerImage = () => { + setBannerImageFile(undefined); + setBannerImageHolder(null); + }; + + const tagHandler = (input: string) => { + const split = input.split(" "); + if (split.length > 1) { + const newSplit: string[] = []; + split.forEach((word) => { + if (word[0] === "#" && word.length > 1) { + setTags((prevTags) => [...prevTags, word]); + } else { + newSplit.push(word); + } + }); + setTagInputValue(newSplit.join(" ")); + } else { + setTagInputValue(input); + } + }; + + const deleteTag = (idx: number) => { + setTags((prevTags) => prevTags.filter((_, index) => index !== idx)); + }; const handleSubmit = async (e: Event) => { e.preventDefault(); @@ -43,20 +154,29 @@ export default function CreatePost() { setError(""); try { + let bannerImageKey = ""; + const bannerFile = bannerImageFile(); + if (bannerFile) { + bannerImageKey = (await AddImageToS3( + bannerFile, + title(), + "blog" + )) as string; + } + const result = await api.database.createPost.mutate({ category: "blog", - title: title(), + title: title().replaceAll(" ", "_"), subtitle: subtitle() || null, body: body() || null, - banner_photo: bannerPhoto() || null, + banner_photo: bannerImageKey !== "" ? bannerImageKey : null, published: published(), tags: tags().length > 0 ? tags() : null, author_id: authState()!.userID }); if (result.data) { - // Redirect to the new post - navigate(`/blog/${encodeURIComponent(title())}`); + navigate(`/blog/${encodeURIComponent(title().replaceAll(" ", "_"))}`); } } catch (err) { console.error("Error creating post:", err); @@ -81,108 +201,100 @@ export default function CreatePost() {
} > -
-
-

- Create Blog Post -

- -
+
+
Create a Blog
+
+ {/* Title */} -
- +
setTitle(e.currentTarget.value)} - class="border-surface2 bg-surface0 w-full rounded-md border px-4 py-2" - placeholder="Enter post title" + required + name="title" + placeholder=" " + class="underlinedInput w-full bg-transparent" /> + +
{/* Subtitle */} -
- +
setSubtitle(e.currentTarget.value)} - class="border-surface2 bg-surface0 w-full rounded-md border px-4 py-2" - placeholder="Enter post subtitle" + name="subtitle" + placeholder=" " + class="underlinedInput w-full bg-transparent" /> + +
- {/* Body */} -
- -