From 65c69a96e5e309aa06416ffc3b274de5c45f6100 Mon Sep 17 00:00:00 2001
From: Bagasbanuna02
Date: Thu, 24 Apr 2025 17:36:21 +0800
Subject: [PATCH] fix stiker di forum
---
src/app/dev/forum/create/page.tsx | 5 +-
src/app/zCoba/text_editor2/page.tsx | 18 +-
.../new/comp_V3_set_html_with_stiker.tsx | 18 ++
...ext_editor.tsx => comp_V3_text_editor.tsx} | 2 +-
.../new/comp_V3_text_editor_stiker.tsx | 284 ++++++++++++++++++
src/app_modules/_global/lib/stiker.ts | 82 ++++-
src/app_modules/_global/ui/ui_modal.tsx | 27 +-
.../comp_V3_create.comment.tsx | 60 +---
.../detail_component/detail_view.tsx | 25 +-
.../component/main_component/card_view.tsx | 25 +-
src/app_modules/forum/create/V3_create.tsx | 265 ++++++++++++++++
src/app_modules/forum/create/new_create.tsx | 4 +-
src/app_modules/forum/edit/posting/index.tsx | 4 +-
13 files changed, 730 insertions(+), 89 deletions(-)
create mode 100644 src/app_modules/_global/component/new/comp_V3_set_html_with_stiker.tsx
rename src/app_modules/_global/component/new/{new_text_editor.tsx => comp_V3_text_editor.tsx} (97%)
create mode 100644 src/app_modules/_global/component/new/comp_V3_text_editor_stiker.tsx
create mode 100644 src/app_modules/forum/create/V3_create.tsx
diff --git a/src/app/dev/forum/create/page.tsx b/src/app/dev/forum/create/page.tsx
index 5d9f38c0..8d2a75aa 100644
--- a/src/app/dev/forum/create/page.tsx
+++ b/src/app/dev/forum/create/page.tsx
@@ -1,11 +1,14 @@
import { Forum_Create } from "@/app_modules/forum";
import Forum_NewCreate from "@/app_modules/forum/create/new_create";
+import { Forum_V3_Create } from "@/app_modules/forum/create/V3_create";
+
export default async function Page() {
return (
<>
{/* */}
-
+ {/* */}
+
>
);
}
diff --git a/src/app/zCoba/text_editor2/page.tsx b/src/app/zCoba/text_editor2/page.tsx
index e2bc55b6..580423c3 100644
--- a/src/app/zCoba/text_editor2/page.tsx
+++ b/src/app/zCoba/text_editor2/page.tsx
@@ -16,6 +16,7 @@ import {
import { useDisclosure } from "@mantine/hooks";
import dynamic from "next/dynamic";
import { MainColor } from "@/app_modules/_global/color";
+import { listStiker } from "@/app_modules/_global/lib/stiker";
// Dynamic import ReactQuill dengan SSR disabled
const ReactQuill = dynamic(
@@ -29,23 +30,6 @@ const ReactQuill = dynamic(
{ ssr: false, loading: () => Loading Editor...
}
);
-const listStiker = [
- {
- id: 1,
- name: "stiker2",
- url: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQN9AKmsBY4yqdn3GueJJEVPJbfmf853gDL4cN8uc9eqsCTiJ1fzhcpywzVP68NCJEA5NQ&usqp=CAU",
- },
- {
- id: 2,
- name: "stiker3",
- url: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS2lkV3ZiQ8m-OELSui2JGVy80vnh1cyRUV7NrgFNluPVVs2HUAyCHwCMAKGe2s5jk2sn8&usqp=CAU",
- },
- {
- id: 3,
- name: "stiker4",
- url: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQHy9ZdsPc6dHgVTl5yIGpRJ-KtpTIsXA2_kbfO1Oc-pv_f7CNKGxhO56RjKujE3xCyb9k&usqp=CAU",
- },
-];
type ChatItem = {
content: string; // HTML content including text and stickers
diff --git a/src/app_modules/_global/component/new/comp_V3_set_html_with_stiker.tsx b/src/app_modules/_global/component/new/comp_V3_set_html_with_stiker.tsx
new file mode 100644
index 00000000..b7b7f542
--- /dev/null
+++ b/src/app_modules/_global/component/new/comp_V3_set_html_with_stiker.tsx
@@ -0,0 +1,18 @@
+
+export function Comp_V3_SetHtmlWithSticker({
+ props,
+ className,
+ color,
+}: {
+ props: string;
+ className: string;
+ color?: string;
+}) {
+ return (
+ <>
+
+ >
+ );
+}
diff --git a/src/app_modules/_global/component/new/new_text_editor.tsx b/src/app_modules/_global/component/new/comp_V3_text_editor.tsx
similarity index 97%
rename from src/app_modules/_global/component/new/new_text_editor.tsx
rename to src/app_modules/_global/component/new/comp_V3_text_editor.tsx
index 94b277bd..daf9f196 100644
--- a/src/app_modules/_global/component/new/new_text_editor.tsx
+++ b/src/app_modules/_global/component/new/comp_V3_text_editor.tsx
@@ -9,7 +9,7 @@ import { maxInputLength } from "../../lib/maximal_setting";
const ReactQuill = dynamic(() => import("react-quill"), { ssr: false });
-export function ComponentTextEditor({
+export function Component_V3_TextEditor({
data,
onSetData,
// lengthData,
diff --git a/src/app_modules/_global/component/new/comp_V3_text_editor_stiker.tsx b/src/app_modules/_global/component/new/comp_V3_text_editor_stiker.tsx
new file mode 100644
index 00000000..e0affdfc
--- /dev/null
+++ b/src/app_modules/_global/component/new/comp_V3_text_editor_stiker.tsx
@@ -0,0 +1,284 @@
+import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
+import {
+ ActionIcon,
+ Box,
+ Button,
+ Group,
+ Image,
+ Paper,
+ ScrollArea,
+ SimpleGrid,
+ Stack,
+ Text,
+ Tooltip,
+} from "@mantine/core";
+import { useDisclosure, useShallowEffect } from "@mantine/hooks";
+import React, { useState } from "react";
+import dynamic from "next/dynamic";
+import { MainColor } from "../../color";
+import { maxInputLength } from "../../lib/maximal_setting";
+import ComponentGlobal_InputCountDown from "../input_countdown";
+import { funReplaceHtml } from "../../fun/fun_replace_html";
+import { forum_funCreate } from "@/app_modules/forum/fun/create/fun_create";
+import {
+ ComponentGlobal_NotifikasiBerhasil,
+ ComponentGlobal_NotifikasiGagal,
+} from "../../notif_global";
+import { useRouter } from "next/navigation";
+import { IconMoodSmileFilled } from "@tabler/icons-react";
+import { listStiker } from "../../lib/stiker";
+import { UIGlobal_Modal } from "../../ui";
+
+const ReactQuill = dynamic(
+ async () => {
+ const { default: RQ } = await import("react-quill");
+ // Tidak perlu import CSS dengan import statement
+ return function comp({ forwardedRef, ...props }: any) {
+ return ;
+ };
+ },
+ {
+ ssr: false,
+ loading: () => (
+
+ Ketik pesan di sini atau tambahkan stiker...
+
+ ),
+ }
+);
+
+export function Component_V3_TextEditorWithStiker({
+ data,
+ onSetData,
+ onSetLengthData,
+}: {
+ data: string;
+ onSetData: (value: string) => void;
+ onSetLengthData: (value: number) => void;
+}) {
+ const router = useRouter();
+ const [editorContent, setEditorContent] = useState("");
+ const [opened, { open, close }] = useDisclosure(false);
+ const quillRef = React.useRef(null);
+ const [quillLoaded, setQuillLoaded] = useState(false);
+ const [isReady, setIsReady] = useState(false);
+
+ useShallowEffect(() => {
+ setIsReady(true); // Set ready on client-side mount
+ }, []);
+
+ useShallowEffect(() => {
+ setQuillLoaded(true); // Set ready on client-side mount
+ }, []);
+
+ const handleChange = (input: string) => {
+ const text = input.replace(/<[^>]+>/g, "").trim(); // Remove HTML tags and trim
+ // if (text.length <= maxInputLength) {
+ // }
+ onSetData(input);
+ onSetLengthData(text.length);
+ // Input diabaikan jika panjang > maxLength
+ };
+
+ useShallowEffect(() => {
+ // Add Quill CSS via tag
+ const link = document.createElement("link");
+ link.href = "https://cdn.quilljs.com/1.3.6/quill.snow.css";
+ link.rel = "stylesheet";
+ document.head.appendChild(link);
+
+ // Add custom style for stickers inside Quill editor
+ const style = document.createElement("style");
+ style.textContent = `
+ .ql-editor img {
+ max-width: 70px !important;
+ max-height: 70px !important;
+ }
+ // .chat-content img {
+ // max-width: 70px !important;
+ // max-height: 70px !important;
+ // }
+ `;
+ document.head.appendChild(style);
+
+ setQuillLoaded(true);
+
+ return () => {
+ // Clean up when component unmounts
+ document.head.removeChild(link);
+ document.head.removeChild(style);
+ };
+ }, []);
+
+ // Custom toolbar options for ReactQuill
+ const modules = {
+ toolbar: [
+ [{ header: [1, 2, false] }],
+ ["bold", "italic", "underline", "strike", "blockquote"],
+ [{ list: "ordered" }, { list: "bullet" }],
+ ["link"],
+ ["clean"],
+ ],
+ };
+
+ const formats = [
+ "header",
+ "bold",
+ "italic",
+ "underline",
+ "strike",
+ "blockquote",
+ "list",
+ "bullet",
+ "link",
+ "image",
+ ];
+
+ const insertSticker = (stickerUrl: string) => {
+ if (!quillRef.current) return;
+
+ const quill = quillRef.current.getEditor();
+ const range = quill.getSelection(true);
+
+ // Custom image insertion with size
+ // Use custom blot or HTML string with size attributes
+ const stickerHtml = `
`;
+
+ // Insert HTML at cursor position
+ quill.clipboard.dangerouslyPasteHTML(range.index, stickerHtml);
+
+ // Move cursor after inserted sticker
+ quill.setSelection(range.index + 1, 0);
+
+ // Focus back on editor
+ quill.focus();
+
+ // Close sticker modal
+ close();
+ };
+
+ return (
+ <>
+ {isReady ? (
+
+ {quillLoaded && (
+
+
+
+
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {listStiker.map((item) => (
+
+
+ insertSticker(item.url)}
+ />
+
+
+ ))}
+
+
+
+ ) : (
+
+ )}
+ >
+ );
+}
+
+interface ButtonActionProps {
+ value: string;
+ lengthData: number;
+}
+
+function ButtonAction({ value, lengthData }: ButtonActionProps) {
+ const router = useRouter();
+ const [loading, setLoading] = useState(false);
+
+ async function onCreate() {
+ try {
+ setLoading(true);
+ const create = await forum_funCreate(value);
+ if (create.status === 201) {
+ ComponentGlobal_NotifikasiBerhasil(create.message);
+ router.back();
+
+ mqtt_client.publish(
+ "Forum_create_new",
+ JSON.stringify({ isNewPost: true, count: 1 })
+ );
+ } else {
+ ComponentGlobal_NotifikasiGagal(create.message);
+ }
+ } catch (error) {
+ console.log(error);
+ } finally {
+ setLoading(false);
+ }
+ }
+
+ return (
+
" ||
+ // value === "" ||
+ // funReplaceHtml({ html: editorContent }).length > maxInputLength
+ // }
+ bg={MainColor.yellow}
+ color="yellow"
+ c="black"
+ radius="xl"
+ loading={loading}
+ loaderPosition="center"
+ onClick={onCreate}
+ >
+ Posting
+
+ );
+}
diff --git a/src/app_modules/_global/lib/stiker.ts b/src/app_modules/_global/lib/stiker.ts
index 237cf009..7ad745b2 100644
--- a/src/app_modules/_global/lib/stiker.ts
+++ b/src/app_modules/_global/lib/stiker.ts
@@ -1,17 +1,89 @@
-export const listStiker = [
+const dummyStiker = [
{
id: 1,
- name: "stiker2",
+ name: "stiker1",
url: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQN9AKmsBY4yqdn3GueJJEVPJbfmf853gDL4cN8uc9eqsCTiJ1fzhcpywzVP68NCJEA5NQ&usqp=CAU",
},
{
id: 2,
- name: "stiker3",
+ name: "stiker2",
url: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS2lkV3ZiQ8m-OELSui2JGVy80vnh1cyRUV7NrgFNluPVVs2HUAyCHwCMAKGe2s5jk2sn8&usqp=CAU",
},
{
id: 3,
- name: "stiker4",
+ name: "stiker3",
url: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQHy9ZdsPc6dHgVTl5yIGpRJ-KtpTIsXA2_kbfO1Oc-pv_f7CNKGxhO56RjKujE3xCyb9k&usqp=CAU",
},
-];
\ No newline at end of file
+ {
+ id: 4,
+ name: "stiker4",
+ url: "https://i.pinimg.com/236x/0a/2e/54/0a2e544c9a908beed6b544d031a444ca.jpg",
+ },
+ {
+ id: 5,
+ name: "stiker5",
+ url: "https://i.pinimg.com/564x/ff/d3/f7/ffd3f7498d09e4fdf48967fb4651b70b.jpg",
+ },
+ {
+ id: 6,
+ name: "stiker6",
+ url: "https://s.cafebazaar.ir/images/icons/com.apikdev.stickerwapentol-4febefdb-b3d4-4436-a241-e5e140ba3e0a_512x512.png?x-img=v1/resize,h_256,w_256,lossless_false/optimize",
+ },
+ {
+ id: 7,
+ name: "stiker7",
+ url: "https://play-lh.googleusercontent.com/MHPScwJ_owQJtf26PpiANC83sGj8d_cPz_83R3XhmFN9nJUuoWHJ0Y-GaEsKhXk4sA",
+ },
+ {
+ id: 8,
+ name: "stiker8",
+ url: "https://i.pinimg.com/236x/34/73/91/3473915a7434885e80ca11728e9b376a.jpg",
+ },
+ {
+ id: 9,
+ name: "stiker9",
+ url: "https://i.pinimg.com/736x/ae/8b/29/ae8b29377f241616e57e5d5745a8984a.jpg",
+ },
+ {
+ id: 10,
+ name: "stiker10",
+ url: "https://i.pinimg.com/564x/cd/da/68/cdda68c895e9e74382d912cbf1161634.jpg",
+ },
+ {
+ id: 11,
+ name: "stiker11",
+ url: "https://i.pinimg.com/564x/7c/af/41/7caf412dd8f5336951a45ca5f8105423.jpg",
+ },
+ {
+ id: 12,
+ name: "stiker12",
+ url: "https://i.pinimg.com/736x/43/55/5a/43555a618afc52331fd9a8effbbb33b1.jpg",
+ },
+ {
+ id: 13,
+ name: "stiker13",
+ url: "https://i.pinimg.com/564x/77/52/b1/7752b14b010db94a40132bf4f7aede8f.jpg",
+ },
+ {
+ id: 14,
+ name: "stiker14",
+ url: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSEeCX_gq9XpK9CwQvEtIwWXlciBHFBP5IpB5YPWR6QqD4TFIs8xj2ezCGzJfMgH4vR34Q&usqp=CAU",
+ },
+ {
+ id: 15,
+ name: "stiker15",
+ url: "https://i.pinimg.com/originals/03/a5/2f/03a52faa637fe35f33316e95b9e3f1ee.gif",
+ },
+ {
+ id: 16,
+ name: "stiker16",
+ url: "https://teknogram.id/gallery/stiker-wa/kartun-bergerak/stiker-kartun-bergerak-3.png",
+ },
+ {
+ id: 17,
+ name: "stiker17",
+ url: "https://id-live-01.slatic.net/p/1cbe0e62964c31030d12cfdf9dadb96b.jpg",
+ },
+];
+
+export const listStiker = dummyStiker;
\ No newline at end of file
diff --git a/src/app_modules/_global/ui/ui_modal.tsx b/src/app_modules/_global/ui/ui_modal.tsx
index fdfcac6e..78116b52 100644
--- a/src/app_modules/_global/ui/ui_modal.tsx
+++ b/src/app_modules/_global/ui/ui_modal.tsx
@@ -1,7 +1,9 @@
"use client";
-import { Modal, Stack, Title, Group, Button, Box } from "@mantine/core";
+import { Modal, Stack, Title, Group, Button, Box, ActionIcon } from "@mantine/core";
import { MainColor, AccentColor } from "../color/color_pallet";
+import React from "react";
+import { IconX } from "@tabler/icons-react";
export default function UIGlobal_Modal({
opened,
@@ -9,19 +11,23 @@ export default function UIGlobal_Modal({
title,
buttonKiri,
buttonKanan,
+ children,
+ closeButton
}: {
opened: any;
close: any;
title: any;
- buttonKiri: any;
- buttonKanan: any;
+ buttonKiri?: any;
+ buttonKanan?: any;
+ children?: React.ReactNode;
+ closeButton?: boolean
}) {
return (
<>
{
- close();
+ close();
}}
centered
withCloseButton={false}
@@ -32,14 +38,19 @@ export default function UIGlobal_Modal({
},
}}
>
-
-
+
+
+
{title}
-
+ {closeButton ?
+
+ : null}
+
+ {children ? children :
{buttonKiri}
{buttonKanan}
-
+ }
>
diff --git a/src/app_modules/forum/component/detail_component/comp_V3_create.comment.tsx b/src/app_modules/forum/component/detail_component/comp_V3_create.comment.tsx
index 853c08bc..5aa95ab6 100644
--- a/src/app_modules/forum/component/detail_component/comp_V3_create.comment.tsx
+++ b/src/app_modules/forum/component/detail_component/comp_V3_create.comment.tsx
@@ -2,8 +2,12 @@
import { MainColor } from "@/app_modules/_global/color/color_pallet";
import ComponentGlobal_InputCountDown from "@/app_modules/_global/component/input_countdown";
+import { funReplaceHtml } from "@/app_modules/_global/fun/fun_replace_html";
+import { maxInputLength } from "@/app_modules/_global/lib/maximal_setting";
+import { listStiker } from "@/app_modules/_global/lib/stiker";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
+import { UIGlobal_Modal } from "@/app_modules/_global/ui";
import notifikasiToUser_funCreate from "@/app_modules/notifikasi/fun/create/create_notif_to_user";
import { clientLogger } from "@/util/clientLogger";
import mqtt_client from "@/util/mqtt_client";
@@ -13,7 +17,6 @@ import {
Button,
Group,
Image,
- Modal,
Paper,
ScrollArea,
SimpleGrid,
@@ -21,20 +24,15 @@ import {
Text,
Tooltip,
} from "@mantine/core";
-import { useRouter } from "next/navigation";
+import { useDisclosure, useShallowEffect } from "@mantine/hooks";
+import { IconMoodSmileFilled, IconX } from "@tabler/icons-react";
+import dynamic from "next/dynamic";
import React, { useState } from "react";
import { forum_funCreateKomentar } from "../../fun/create/fun_create_komentar";
import {
MODEL_FORUM_KOMENTAR,
MODEL_FORUM_POSTING,
} from "../../model/interface";
-import dynamic from "next/dynamic";
-import { useDisclosure, useShallowEffect } from "@mantine/hooks";
-import { listStiker } from "@/app_modules/_global/lib/stiker";
-import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
-import { maxInputLength } from "@/app_modules/_global/lib/maximal_setting";
-import { funReplaceHtml } from "@/app_modules/_global/fun/fun_replace_html";
-import { IconMoodSmileFilled, IconX } from "@tabler/icons-react";
const ReactQuill = dynamic(
async () => {
@@ -54,9 +52,6 @@ const ReactQuill = dynamic(
}
);
-type ChatItem = {
- content: string; // HTML content including text and stickers
-};
export default function Forum_V3_CreateKomentar({
postingId,
data,
@@ -299,15 +294,11 @@ export default function Forum_V3_CreateKomentar({
)}
- {/* {JSON.stringify(editorContent, null, 2)} */}
-
- {/* Sticker Modal */}
-
{listStiker.map((item) => (
@@ -325,36 +316,7 @@ export default function Forum_V3_CreateKomentar({
))}
-
-
- {/*
-
-
-
- */}
+
>
);
diff --git a/src/app_modules/forum/component/detail_component/detail_view.tsx b/src/app_modules/forum/component/detail_component/detail_view.tsx
index 7f36366b..4205a409 100644
--- a/src/app_modules/forum/component/detail_component/detail_view.tsx
+++ b/src/app_modules/forum/component/detail_component/detail_view.tsx
@@ -5,6 +5,8 @@ import { Box, Group, Stack, Text } from "@mantine/core";
import { IconMessageCircle, IconMessageCircleX } from "@tabler/icons-react";
import { MODEL_FORUM_POSTING } from "../../model/interface";
import ComponentForum_DetailHeader from "./detail_header";
+import { useShallowEffect } from "@mantine/hooks";
+import { Comp_V3_SetHtmlWithSticker } from "@/app_modules/_global/component/new/comp_V3_set_html_with_stiker";
export default function ComponentForum_DetailForumView({
data,
@@ -17,6 +19,22 @@ export default function ComponentForum_DetailForumView({
userLoginId: string;
onLoadData: (val: any) => void;
}) {
+ useShallowEffect(() => {
+ // Add custom style for stickers inside Quill editor
+ const style = document.createElement("style");
+ style.textContent = `
+ .chat-content img {
+ max-width: 70px !important;
+ max-height: 70px !important;
+ }
+ `;
+ document.head.appendChild(style);
+ return () => {
+ // Clean up when component unmounts
+ document.head.removeChild(style);
+ };
+ }, []);
+
return (
<>
@@ -31,10 +49,13 @@ export default function ComponentForum_DetailForumView({
/>
{/* CONTENT */}
-
+
{data?.diskusi ? (
-
+
) : (
""
)}
diff --git a/src/app_modules/forum/component/main_component/card_view.tsx b/src/app_modules/forum/component/main_component/card_view.tsx
index 1d271af2..df391804 100644
--- a/src/app_modules/forum/component/main_component/card_view.tsx
+++ b/src/app_modules/forum/component/main_component/card_view.tsx
@@ -11,6 +11,8 @@ import { useRouter } from "next/navigation";
import { useState } from "react";
import { MODEL_FORUM_POSTING } from "../../model/interface";
import ComponentForum_BerandaHeaderCard from "./card_header";
+import { Comp_V3_SetHtmlWithSticker } from "@/app_modules/_global/component/new/comp_V3_set_html_with_stiker";
+import { useShallowEffect } from "@mantine/hooks";
export default function ComponentForum_BerandaCardView({
data,
@@ -26,6 +28,22 @@ export default function ComponentForum_BerandaCardView({
const router = useRouter();
const [visible, setVisible] = useState(false);
+ useShallowEffect(() => {
+ // Add custom style for stickers inside Quill editor
+ const style = document.createElement("style");
+ style.textContent = `
+ .chat-content img {
+ max-width: 70px !important;
+ max-height: 70px !important;
+ }
+ `;
+ document.head.appendChild(style);
+ return () => {
+ // Clean up when component unmounts
+ document.head.removeChild(style);
+ };
+ }, []);
+
return (
<>
@@ -45,8 +63,11 @@ export default function ComponentForum_BerandaCardView({
setVisible(true), router.push(RouterForum.main_detail + data?.id);
}}
>
-
-
+
+
diff --git a/src/app_modules/forum/create/V3_create.tsx b/src/app_modules/forum/create/V3_create.tsx
new file mode 100644
index 00000000..6f604d38
--- /dev/null
+++ b/src/app_modules/forum/create/V3_create.tsx
@@ -0,0 +1,265 @@
+"use client";
+
+import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
+import {
+ ActionIcon,
+ Box,
+ Button,
+ Group,
+ Image,
+ Paper,
+ ScrollArea,
+ SimpleGrid,
+ Stack,
+ Text,
+ Tooltip,
+} from "@mantine/core";
+import { useDisclosure, useShallowEffect } from "@mantine/hooks";
+import React, { useState } from "react";
+import dynamic from "next/dynamic";
+import { useRouter } from "next/navigation";
+import { MainColor } from "@/app_modules/_global/color";
+import { ComponentGlobal_InputCountDown } from "@/app_modules/_global/component";
+import { funReplaceHtml } from "@/app_modules/_global/fun/fun_replace_html";
+import { maxInputLength } from "@/app_modules/_global/lib/maximal_setting";
+import { listStiker } from "@/app_modules/_global/lib/stiker";
+import {
+ ComponentGlobal_NotifikasiBerhasil,
+ ComponentGlobal_NotifikasiGagal,
+} from "@/app_modules/_global/notif_global";
+import { UIGlobal_Modal } from "@/app_modules/_global/ui";
+import { IconMoodSmileFilled } from "@tabler/icons-react";
+import { forum_funCreate } from "../fun/create/fun_create";
+
+const ReactQuill = dynamic(
+ async () => {
+ const { default: RQ } = await import("react-quill");
+ // Tidak perlu import CSS dengan import statement
+ return function comp({ forwardedRef, ...props }: any) {
+ return ;
+ };
+ },
+ {
+ ssr: false,
+ loading: () => (
+
+ Ketik pesan di sini atau tambahkan stiker...
+
+ ),
+ }
+);
+
+export function Forum_V3_Create() {
+ const router = useRouter();
+ const [editorContent, setEditorContent] = useState("");
+ const [opened, { open, close }] = useDisclosure(false);
+ const quillRef = React.useRef(null);
+ const [quillLoaded, setQuillLoaded] = useState(false);
+ const [isReady, setIsReady] = useState(false);
+
+ useShallowEffect(() => {
+ setIsReady(true); // Set ready on client-side mount
+ }, []);
+
+ useShallowEffect(() => {
+ setQuillLoaded(true); // Set ready on client-side mount
+ }, []);
+
+ useShallowEffect(() => {
+ // Add Quill CSS via tag
+ const link = document.createElement("link");
+ link.href = "https://cdn.quilljs.com/1.3.6/quill.snow.css";
+ link.rel = "stylesheet";
+ document.head.appendChild(link);
+
+ // Add custom style for stickers inside Quill editor
+ const style = document.createElement("style");
+ style.textContent = `
+ .ql-editor img {
+ max-width: 70px !important;
+ max-height: 70px !important;
+ }
+ // .chat-content img {
+ // max-width: 70px !important;
+ // max-height: 70px !important;
+ // }
+ `;
+ document.head.appendChild(style);
+
+ setQuillLoaded(true);
+
+ return () => {
+ // Clean up when component unmounts
+ document.head.removeChild(link);
+ document.head.removeChild(style);
+ };
+ }, []);
+
+ // Custom toolbar options for ReactQuill
+ const modules = {
+ toolbar: [
+ [{ header: [1, 2, false] }],
+ ["bold", "italic", "underline", "strike", "blockquote"],
+ [{ list: "ordered" }, { list: "bullet" }],
+ ["link"],
+ ["clean"],
+ ],
+ };
+
+ const formats = [
+ "header",
+ "bold",
+ "italic",
+ "underline",
+ "strike",
+ "blockquote",
+ "list",
+ "bullet",
+ "link",
+ "image",
+ ];
+
+ const insertSticker = (stickerUrl: string) => {
+ if (!quillRef.current) return;
+
+ const quill = quillRef.current.getEditor();
+ const range = quill.getSelection(true);
+
+ // Custom image insertion with size
+ // Use custom blot or HTML string with size attributes
+ const stickerHtml = `
`;
+
+ // Insert HTML at cursor position
+ quill.clipboard.dangerouslyPasteHTML(range.index, stickerHtml);
+
+ // Move cursor after inserted sticker
+ quill.setSelection(range.index + 1, 0);
+
+ // Focus back on editor
+ quill.focus();
+
+ // Close sticker modal
+ close();
+ };
+
+ return (
+ <>
+ {isReady ? (
+
+ {quillLoaded && (
+
+
+
+
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {listStiker.map((item) => (
+
+
+ insertSticker(item.url)}
+ />
+
+
+ ))}
+
+
+
+ ) : (
+
+ )}
+ >
+ );
+}
+
+interface ButtonActionProps {
+ value: string;
+}
+
+function ButtonAction({ value }: ButtonActionProps) {
+ const router = useRouter();
+ const [loading, setLoading] = useState(false);
+
+ async function onCreate() {
+ try {
+ setLoading(true);
+ const create = await forum_funCreate(value);
+ if (create.status === 201) {
+ ComponentGlobal_NotifikasiBerhasil(create.message);
+ router.back();
+
+ mqtt_client.publish(
+ "Forum_create_new",
+ JSON.stringify({ isNewPost: true, count: 1 })
+ );
+ } else {
+ ComponentGlobal_NotifikasiGagal(create.message);
+ }
+ } catch (error) {
+ console.log(error);
+ } finally {
+ setLoading(false);
+ }
+ }
+
+ return (
+
+ );
+}
diff --git a/src/app_modules/forum/create/new_create.tsx b/src/app_modules/forum/create/new_create.tsx
index 61f2b1e0..051ad4c0 100644
--- a/src/app_modules/forum/create/new_create.tsx
+++ b/src/app_modules/forum/create/new_create.tsx
@@ -2,7 +2,6 @@
import { MainColor } from "@/app_modules/_global/color/color_pallet";
import ComponentGlobal_InputCountDown from "@/app_modules/_global/component/input_countdown";
-import { ComponentTextEditor } from "@/app_modules/_global/component/new/new_text_editor";
import { maxInputLength } from "@/app_modules/_global/lib/maximal_setting";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
@@ -12,6 +11,7 @@ import { useRouter } from "next/navigation";
import { useState } from "react";
import "react-quill/dist/quill.snow.css";
import { forum_funCreate } from "../fun/create/fun_create";
+import { Component_V3_TextEditor } from "@/app_modules/_global/component/new/comp_V3_text_editor";
export default function Forum_NewCreate() {
const [data, setData] = useState("");
@@ -19,7 +19,7 @@ export default function Forum_NewCreate() {
return (
- {
setData(val);
diff --git a/src/app_modules/forum/edit/posting/index.tsx b/src/app_modules/forum/edit/posting/index.tsx
index a431307c..78bab78c 100644
--- a/src/app_modules/forum/edit/posting/index.tsx
+++ b/src/app_modules/forum/edit/posting/index.tsx
@@ -2,7 +2,7 @@
import { MainColor } from "@/app_modules/_global/color/color_pallet";
import ComponentGlobal_InputCountDown from "@/app_modules/_global/component/input_countdown";
-import { ComponentTextEditor } from "@/app_modules/_global/component/new/new_text_editor";
+import { Component_V3_TextEditor } from "@/app_modules/_global/component/new/comp_V3_text_editor";
import { funReplaceHtml } from "@/app_modules/_global/fun/fun_replace_html";
import { maxInputLength } from "@/app_modules/_global/lib/maximal_setting";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
@@ -45,7 +45,7 @@ export default function Forum_EditPosting() {
return (
<>
- {
setData({