From 9dc4b640662f3042f8c1d92d4e755a21e28ecb44 Mon Sep 17 00:00:00 2001 From: Sabda Yagra Date: Mon, 30 Jun 2025 13:25:00 +0700 Subject: [PATCH] QUDO-270 --- .../supervisor/knowledge-base/import/page.tsx | 253 ++++++++++++++++++ .../supervisor/knowledge-base/page.tsx | 13 +- 2 files changed, 262 insertions(+), 4 deletions(-) create mode 100644 app/[locale]/(protected)/supervisor/knowledge-base/import/page.tsx diff --git a/app/[locale]/(protected)/supervisor/knowledge-base/import/page.tsx b/app/[locale]/(protected)/supervisor/knowledge-base/import/page.tsx new file mode 100644 index 00000000..6e4f1964 --- /dev/null +++ b/app/[locale]/(protected)/supervisor/knowledge-base/import/page.tsx @@ -0,0 +1,253 @@ +"use client"; + +import React, { useState, useEffect, useCallback } from "react"; +import Swal from "sweetalert2"; +import withReactContent from "sweetalert2-react-content"; +import { close, error, loading } from "@/config/swal"; +import { + getKnowledgeBaseCategoryList, + saveKnowledgeBase, +} from "@/service/master/knowledge-base"; +import { Link, useRouter } from "@/i18n/routing"; + +type ButtonProps = { + title: string; + type: "submit" | "link"; + href?: string; +}; + +type KnowledgeBaseItem = { + category: string; + title: string; + question: string; + answer: string; +}; + +type CategoryItem = { + id: string; + name: string; +}; + +const Button: React.FC = ({ title, type, href }) => { + if (type === "submit") { + return ( + + ); + } + + return ( + + + + ); +}; + +const ImportKnowledgeBase: React.FC = () => { + const router = useRouter(); + const [listCategory, setListCategory] = useState([]); + const [file, setFile] = useState(null); + const [savedArray, setSavedArray] = useState([]); + const [handleDelete, setHandleDelete] = useState(false); + const MySwal = withReactContent(Swal); + + + useEffect(() => { + async function initState() { + loading(); + const response = await getKnowledgeBaseCategoryList(); + const data = response?.data?.data || []; + setListCategory(data); + close(); + } + initState(); + }, []); + + const handleOnChange = (e: React.ChangeEvent) => { + if (e.target.files && e.target.files[0]) { + setFile(e.target.files[0]); + } + }; + + const csvFileToArray = (content: string) => { + const csvHeader = ["category", "title", "question", "answer"]; + const rows = content.split("\n").filter((line) => line.trim() !== ""); + + const parsedData: KnowledgeBaseItem[] = rows.map((row) => { + const values = row.split(";").map((v) => v.trim()); + const obj = csvHeader.reduce((acc, header, index) => { + acc[header as keyof KnowledgeBaseItem] = values[index] || ""; + return acc; + }, {} as KnowledgeBaseItem); + return obj; + }); + + setSavedArray(parsedData); + setHandleDelete(true); + }; + + const handleOnSubmit = useCallback( + (e: React.FormEvent) => { + e.preventDefault(); + if (file) { + const reader = new FileReader(); + reader.onload = (event) => { + const text = event.target?.result as string; + csvFileToArray(text); + }; + reader.readAsText(file); + } + }, + [file] + ); + + const handleSave = async (data: KnowledgeBaseItem[]) => { + const result = await MySwal.fire({ + title: "Simpan Data", + icon: "warning", + showCancelButton: true, + cancelButtonColor: "#d33", + confirmButtonColor: "#3085d6", + confirmButtonText: "Simpan", + }); + + if (result.isConfirmed) { + save(data); + } + }; + + const save = async (data: KnowledgeBaseItem[]) => { + loading(); + for (const item of data) { + const categoryStringId = listCategory.find( + (c) => c.name.toLowerCase() === item.category.toLowerCase() + )?.id; + + const reqData = { + title: item.title, + categoryId: categoryStringId, + question: item.question, + answer: item.answer, + }; + + const response = await saveKnowledgeBase(reqData); + if (response?.error) { + error(response.message); + close(); + return; + } + } + close(); + successSubmit("/supervisor/knowledge-base"); + }; + + const successSubmit = async (redirect: string) => { + const result = await MySwal.fire({ + title: "Sukses", + icon: "success", + confirmButtonColor: "#3085d6", + confirmButtonText: "OK", + }); + + if (result.isConfirmed) { + router.push(redirect); + } + }; + + const deleteFile = () => { + setFile(null); + setSavedArray([]); + setHandleDelete(false); + }; + + return ( +
+
+
+ + + +
+ + {savedArray.length > 0 && ( +
+ + + + + + + + + + + {savedArray.map((item, idx) => ( + + + + + + + ))} + +
KategoriJudulPertanyaanJawaban
{item.category}{item.title}{item.question}{item.answer}
+
+ )} + + {handleDelete && ( + + )} + +
+ + + + {handleDelete && ( + + )} +
+
+
+ ); +}; + +export default ImportKnowledgeBase; diff --git a/app/[locale]/(protected)/supervisor/knowledge-base/page.tsx b/app/[locale]/(protected)/supervisor/knowledge-base/page.tsx index 7f4c083f..c517cbc9 100644 --- a/app/[locale]/(protected)/supervisor/knowledge-base/page.tsx +++ b/app/[locale]/(protected)/supervisor/knowledge-base/page.tsx @@ -46,6 +46,7 @@ import { useForm } from "react-hook-form"; import { z } from "zod"; import { toast } from "@/components/ui/use-toast"; import { Textarea } from "@/components/ui/textarea"; +import { Link, useRouter } from "@/i18n/routing"; const FormSchema = z.object({ name: z.string().min(2, { @@ -67,6 +68,7 @@ const FormSchemaCreate = z.object({ const KnowledgeBase = () => { const MySwal = withReactContent(Swal); + const router = useRouter(); const [categories, setCategories] = useState([]); const [questions, setQuestions] = useState([]); const [selectedCategoryId, setSelectedCategoryId] = useState(0); @@ -318,14 +320,17 @@ const KnowledgeBase = () => { ))}
- + + +