+ {/* Description with ReactQuill */}
+
-
+ {formErrors.comment && (
+
+ )}
{/* Submit Button */}
diff --git a/src/ui/pages/LeaveAndAdjustments/tabs/PtoLeaveTab.tsx b/src/ui/pages/LeaveAndAdjustments/tabs/PtoLeaveTab.tsx
index 0885777..74541c2 100644
--- a/src/ui/pages/LeaveAndAdjustments/tabs/PtoLeaveTab.tsx
+++ b/src/ui/pages/LeaveAndAdjustments/tabs/PtoLeaveTab.tsx
@@ -1,5 +1,9 @@
// PtoLeaveTab.tsx
-import React, { useState } from "react";
+import React, { useEffect, useRef, useState } from "react";
+import { quillModules } from "../../../utils/quillConfig";
+import ReactQuill from "react-quill-new";
+import Quill from "quill";
+import "quill/dist/quill.snow.css"; // correct CSS
interface LeaveFormData {
fromDate: string;
@@ -17,9 +21,43 @@ const PtoLeaveTab: React.FC<{
toDate: "",
comment: "",
});
+ const quillRef = useRef
(null);
const [errors, setErrors] = useState>({});
+ useEffect(() => {
+ const editor = quillRef.current?.getEditor();
+
+ if (!editor) return;
+
+ editor.getModule("clipboard").addMatcher(Node.ELEMENT_NODE, (node: any, delta: any) => {
+ return delta;
+ });
+
+ editor.root.addEventListener("paste", async (e: any) => {
+ const items = e.clipboardData?.items;
+
+ if (!items) return;
+
+ for (const item of items) {
+ if (item.type.indexOf("image") === 0) {
+ const file = item.getAsFile();
+ const base64 = await convertToBase64(file);
+
+ const range = editor.getSelection();
+ editor.insertEmbed(range.index, "image", base64);
+ }
+ }
+ });
+ }, []);
+
+ const convertToBase64 = (file: File): Promise =>
+ new Promise((resolve) => {
+ const reader = new FileReader();
+ reader.onload = () => resolve(reader.result as string);
+ reader.readAsDataURL(file);
+ });
+
const validate = () => {
const e: Partial = {};
@@ -56,6 +94,30 @@ const PtoLeaveTab: React.FC<{
return e;
};
+ const resetForm = () => {
+ const emptyForm: LeaveFormData = {
+ fromDate: "",
+ toDate: "",
+ comment: ""
+ };
+
+ setPtoLeave(emptyForm);
+ setErrors({});
+
+ // Properly reset the Quill editor
+ if (quillRef.current) {
+ const editor = quillRef.current.getEditor();
+ editor.setContents([]); // Clear editor contents completely
+ }
+ };
+
+ const handleChange = (field: keyof LeaveFormData, value: string) => {
+ setPtoLeave(prev => ({ ...prev, [field]: value }));
+ if (errors[field]) {
+ setErrors(prev => ({ ...prev, [field]: undefined }));
+ }
+ };
+
const handleSubmit = async () => {
const e = validate();
if (Object.keys(e).length) return setErrors(e);
@@ -68,14 +130,13 @@ const PtoLeaveTab: React.FC<{
});
if (success) {
- setPtoLeave({ fromDate: "", toDate: "", comment: "" });
- setErrors({});
+ resetForm();
alert("PTO submitted!");
}
};
return (
-
+
{/* From Date */}
@@ -88,7 +149,7 @@ const PtoLeaveTab: React.FC<{
disabled={isSubmitting}
value={ptoLeave.fromDate}
min={new Date().toISOString().split("T")[0]}
- onChange={(e) => setPtoLeave({ ...ptoLeave, fromDate: e.target.value })}
+ onChange={(e) => handleChange('fromDate', e.target.value)}
className={`input input-bordered input-sm ${errors.fromDate ? "input-error" : ""
}`}
/>
@@ -105,7 +166,7 @@ const PtoLeaveTab: React.FC<{
disabled={isSubmitting}
value={ptoLeave.toDate}
min={new Date().toISOString().split("T")[0]}
- onChange={(e) => setPtoLeave({ ...ptoLeave, toDate: e.target.value })}
+ onChange={(e) => handleChange('toDate', e.target.value)}
className={`input input-bordered input-sm ${errors.toDate ? "input-error" : ""
}`}
/>
@@ -113,26 +174,27 @@ const PtoLeaveTab: React.FC<{
{/* Comment */}
-
+
+ {errors.comment &&
{errors.comment}
}