From c36cc8f0aa954aa14c0bb7a3f557ade468540e6d Mon Sep 17 00:00:00 2001 From: amd123 Date: Wed, 24 Apr 2024 11:14:06 +0700 Subject: [PATCH 01/25] update --- .../admin/(basic-form)/form-vertical/page.tsx | 8 +- .../admin/article/detail/[id]/page.tsx | 10 + app/(admin)/admin/article/edit/[id]/page.tsx | 10 + app/(admin)/admin/master-menu/page.tsx | 7 + components/Landing Page/MedolUpdate.tsx | 49 ++- components/form/form-article.tsx | 123 ++++++-- components/form/form-detail-article.tsx | 295 ++++++++++++++++++ components/form/form-edit-article.tsx | 294 +++++++++++++++++ components/sidebar/sidebar.tsx | 22 +- components/table/article-table.tsx | 77 +++-- service/article.ts | 27 +- service/http-config/axios-base-service.ts | 67 ++++ service/http-config/mediahub-base-service.ts | 12 + service/medol-news-update.ts | 8 + styles/globals.css | 1 + 15 files changed, 928 insertions(+), 82 deletions(-) create mode 100644 app/(admin)/admin/article/detail/[id]/page.tsx create mode 100644 app/(admin)/admin/article/edit/[id]/page.tsx create mode 100644 app/(admin)/admin/master-menu/page.tsx create mode 100644 components/form/form-detail-article.tsx create mode 100644 components/form/form-edit-article.tsx create mode 100644 service/http-config/mediahub-base-service.ts create mode 100644 service/medol-news-update.ts diff --git a/app/(admin)/admin/(basic-form)/form-vertical/page.tsx b/app/(admin)/admin/(basic-form)/form-vertical/page.tsx index 1667561..61ca9f4 100644 --- a/app/(admin)/admin/(basic-form)/form-vertical/page.tsx +++ b/app/(admin)/admin/(basic-form)/form-vertical/page.tsx @@ -1,11 +1,9 @@ "use client" -import CreateValidationForm from "@/components/form/form-validation/validation-form"; -import CreateVerticalForm from "@/components/form/form-vertical/vertical-form"; -import { Card, Divider, Image } from "@nextui-org/react"; +import { Image } from "@nextui-org/react"; export default function VerticalPage() { return ( -
+
@@ -25,7 +23,7 @@ export default function VerticalPage() {
- + {/* */}
); diff --git a/app/(admin)/admin/article/detail/[id]/page.tsx b/app/(admin)/admin/article/detail/[id]/page.tsx new file mode 100644 index 0000000..ef37625 --- /dev/null +++ b/app/(admin)/admin/article/detail/[id]/page.tsx @@ -0,0 +1,10 @@ +import FormDetailArticle from '@/components/form/form-detail-article' +import { Card } from '@nextui-org/react' + +export default function DetailArticlePage() { + return ( + + + + ) +} diff --git a/app/(admin)/admin/article/edit/[id]/page.tsx b/app/(admin)/admin/article/edit/[id]/page.tsx new file mode 100644 index 0000000..c8ad851 --- /dev/null +++ b/app/(admin)/admin/article/edit/[id]/page.tsx @@ -0,0 +1,10 @@ +import FormUpdateArticle from '@/components/form/form-edit-article' +import { Card } from '@nextui-org/react' + +export default function UpdateArticlePage() { + return ( + + + + ) +} diff --git a/app/(admin)/admin/master-menu/page.tsx b/app/(admin)/admin/master-menu/page.tsx new file mode 100644 index 0000000..b55c9bd --- /dev/null +++ b/app/(admin)/admin/master-menu/page.tsx @@ -0,0 +1,7 @@ +import React from 'react' + +export default function MasterMenuPage() { + return ( +
MasterMenuPage
+ ) +} diff --git a/components/Landing Page/MedolUpdate.tsx b/components/Landing Page/MedolUpdate.tsx index af27a03..a975a7c 100644 --- a/components/Landing Page/MedolUpdate.tsx +++ b/components/Landing Page/MedolUpdate.tsx @@ -1,12 +1,25 @@ import { Button, Card, CardBody, CardFooter, Image, Tab, Tabs } from '@nextui-org/react'; -import React from 'react' +import React, { useEffect, useState } from 'react' import { Swiper, SwiperSlide } from 'swiper/react'; import 'swiper/css'; import 'swiper/css/navigation'; import 'swiper/css/pagination'; import { Navigation, Pagination } from 'swiper/modules'; +import { top5NewsMediahub } from '@/service/medol-news-update'; +import Link from 'next/link'; export default function MedolUpdate() { + const [mediahubUpdate, setMediahubUpdate] = useState(); + + useEffect(() => { + async function getMedihubUpdate() { + const res = await top5NewsMediahub(); + setMediahubUpdate(res.data?.data?.content); + // console.log("List Top5News", res.data.data?.content); + } + + getMedihubUpdate() + }, []); const mediaHubUpdate = [ { @@ -66,23 +79,25 @@ export default function MedolUpdate() { slidesPerView={2} pagination={true} className="mySwiper"> - {mediaHubUpdate.map((newsItem) => ( + {mediahubUpdate?.map((newsItem: any) => ( - - - tes - - -

02-04-2024 09:31 WITA

- Peringatan Nuzulul Quran, Kapolda Sulbar Harap Kegiatan Ini Tambah Wawasan dan -
-
+ + + + tes + + +

02-04-2024 09:31 WITA

+ {newsItem?.title} +
+
+
))} diff --git a/components/form/form-article.tsx b/components/form/form-article.tsx index 55e99a0..d36f28b 100644 --- a/components/form/form-article.tsx +++ b/components/form/form-article.tsx @@ -1,7 +1,7 @@ 'use client' import { Button, Card, Chip, Input, Select, SelectItem, Selection } from '@nextui-org/react' import JoditEditor from 'jodit-react'; -import React, { useRef, useState } from 'react' +import React, { ChangeEvent, useRef, useState } from 'react' import * as z from "zod"; import Swal from 'sweetalert2'; import withReactContent from 'sweetalert2-react-content'; @@ -9,6 +9,8 @@ import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { createArticle } from '@/service/article'; import { error } from '@/config/swal'; +import { useRouter } from 'next/navigation'; +import Link from 'next/link'; const articleSchema = z.object({ title: z.string().min(1, { message: "Required" }), @@ -20,6 +22,7 @@ const articleSchema = z.object({ }); export default function FormArticle() { + const router = useRouter(); const [id, setId] = useState(); const [title, setTitle] = useState(""); const [article, setArticle] = React.useState(new Set([])); @@ -29,6 +32,7 @@ export default function FormArticle() { const editor = useRef(null); const [content, setContent] = useState(''); const MySwal = withReactContent(Swal); + const [selectedImages, setSelectedImages] = useState([]); const formOptions = { resolver: zodResolver(articleSchema) }; type MicroIssueSchema = z.infer; @@ -51,16 +55,29 @@ export default function FormArticle() { }, ] - const CategoryArticle = [ - { - key: 1, - label: "Article" - }, - { - key: 2, - label: "Magazine" - }, - ] + const handleImageChange = (event: ChangeEvent) => { + if (event.target.files) { + const files = Array.from(event.target.files); + setSelectedImages((prevImages) => [...prevImages, ...files]); + } + }; + + const handleRemoveImage = (index: number) => { + setSelectedImages((prevImages) => + prevImages.filter((_, i) => i !== index) + ); + }; + + // const handleSubmitImage = (event: any) => { + // event.preventDefault(); + // // Lakukan penanganan pengunggahan gambar di sini + // if (selectedImage) { + // console.log('Gambar yang dipilih:', selectedImage); + // // Anda dapat melakukan pengunggahan gambar ke server di sini + // } else { + // console.log('Pilih gambar terlebih dahulu.'); + // } + // }; const handleClose = (tagsToRemove: string) => { setTags(tags.filter((tag) => tag !== tagsToRemove)); @@ -84,29 +101,40 @@ export default function FormArticle() { }; - async function save(data: any,) { + async function save(data: any) { const formData = { - id: id, - title, - jenisArtikel: article, - slug, - tags, + title: title, + typeId: parseInt(String(Array.from(article)[0])), + slug: slug, + tags: tags.join(','), description: content, + htmlDescription: content, }; console.log("Form Data:", formData); - if (id != undefined) { - formData.id = id; - } - const response = await createArticle(formData); if (response?.error) { error(response.message); return false; } + + successSubmit("/admin/article"); }; + function successSubmit(redirect: any) { + MySwal.fire({ + title: "Sukses", + icon: "success", + confirmButtonColor: "#3085d6", + confirmButtonText: "OK", + }).then((result) => { + if (result.isConfirmed) { + router.push(redirect); + } + }); + } + async function onSubmit(data: any) { MySwal.fire({ title: "Simpan Data", @@ -246,17 +274,54 @@ export default function FormArticle() {

- + + { + selectedImages?.length > 0 ? +
+

Pratinjau:

+
+ {selectedImages.map((image, index) => ( +
+ handleRemoveImage(index)} + > + X + + Pratinjau Gambar +
+ ))} +
+
+ : "" + } + + +
+ + + +
- diff --git a/components/form/form-detail-article.tsx b/components/form/form-detail-article.tsx new file mode 100644 index 0000000..66e8fbc --- /dev/null +++ b/components/form/form-detail-article.tsx @@ -0,0 +1,295 @@ +'use client' +import { getArticleById } from '@/service/article'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { Button, Card, Chip, Input, Select, SelectItem } from '@nextui-org/react'; +import JoditEditor from 'jodit-react'; +import Link from 'next/link'; +import { usePathname } from 'next/navigation'; +import { useEffect, useRef, useState } from 'react'; +import { useForm } from 'react-hook-form'; +import Swal from 'sweetalert2'; +import withReactContent from 'sweetalert2-react-content'; +import * as z from "zod"; + +const articleSchema = z.object({ + title: z.string().min(1, { message: "Required" }), + article: z.string().min(1, { message: "Required" }), + slug: z.string().min(1, { message: "Required" }), + tags: z.string().min(0, { message: "Required" }).optional(), + description: z.string().min(1, { message: "Required" }).optional(), + +}); + +export default function FormDetailArticle() { + // const [id, setId] = useState(); + const [title, setTitle] = useState(""); + const [slug, setSlug] = useState(""); + const [tags, setTags] = useState([]); + const [newTags, setNewTags] = useState(""); + const editor = useRef(null); + const [content, setContent] = useState(''); + const MySwal = withReactContent(Swal); + const [article, setArticle] = useState(); + const pathname = usePathname(); + const splitPathname = pathname.split('/'); + const id = splitPathname[splitPathname.length - 1]; + console.log(id, "pathnamesplit") + + const formOptions = { resolver: zodResolver(articleSchema) }; + type MicroIssueSchema = z.infer; + const { + register, + control, + handleSubmit, + setValue, + formState: { errors }, + } = useForm(formOptions); + + const editorConfig = { + readonly: true, + } + + const TypeId = [ + { + key: 1, + label: "Article" + }, + { + key: 2, + label: "Magazine" + }, + ] + + const CategoryArticle = [ + { + key: 1, + label: "Article" + }, + { + key: 2, + label: "Magazine" + }, + ] + + const handleClose = (tagsToRemove: string) => { + setTags(tags.filter((tag) => tag !== tagsToRemove)); + if (tags.length === 1) { + setTags([]); + } + }; + + const handleAddTags = (e: any) => { + if (newTags.trim() !== "") { + setTags([...tags, newTags.trim()]); + setNewTags(""); + e.preventDefault(); + } + }; + + const handleKeyDown = (event: any) => { + if (event.key === "Enter") { + handleAddTags(event); + } + }; + + + useEffect(() => { + async function initState() { + const res = await getArticleById(id); + setArticle(res.data?.data); + setTitle(res.data?.data?.title) + console.log("Data Aritcle", res.data?.data); + } + + initState(); + }, []); + + + async function save(data: any,) { + const formData = { + id: id, + title: title, + typeId: parseInt(String(Array.from(article)[0])), + slug: slug, + tags: tags.join(','), + description: content, + htmlDescription: content + }; + + console.log("Form Data:", formData); + // const response = await createArticle(formData); + + // if (response?.error) { + // error(response.message); + // return false; + // } + }; + + async function onSubmit(data: any) { + MySwal.fire({ + title: "Simpan Data", + text: "", + icon: "warning", + showCancelButton: true, + cancelButtonColor: "#d33", + confirmButtonColor: "#3085d6", + confirmButtonText: "Simpan", + }).then((result) => { + if (result.isConfirmed) { + save(data); + } + }); + } + return ( +
+
+ +
+ +
+ {(title.length === 0 && errors.title) && errors.title.message} + +
+
+
+ +
+ {errors.article?.message} +
+ {/*

{article}

*/} +
+
+ setSlug(e.target.value)} + label="Slug" + variant='bordered' + placeholder="Enter Text" + labelPlacement='outside' + /> +
+ {(slug.length === 0 && errors.slug) && errors.slug.message} +
+
+
+

Tags

+ {/* setNewTags(e.target.value)} + onKeyDown={handleKeyDown} + placeholder="Tambahkan tag baru dan tekan Enter" + /> */} +
+ {(tags.length === 0 && errors.tags) && errors.tags.message} +
+
+ handleClose("close")}> + {article?.tags} + +
+
+
+

Description

+ setContent(newContent)} + className="dark:text-black" + + /> +
+ {(content.length === 0 && errors.description) && errors.description.message} +
+
+
+

Attachment (Opsional)

+
+ +
+
+
+ + + + +
+
+
+
+ ) +} diff --git a/components/form/form-edit-article.tsx b/components/form/form-edit-article.tsx new file mode 100644 index 0000000..b3531ee --- /dev/null +++ b/components/form/form-edit-article.tsx @@ -0,0 +1,294 @@ +'use client' +import { getArticleById } from '@/service/article'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { Button, Card, Chip, Input, Select, SelectItem } from '@nextui-org/react'; +import JoditEditor from 'jodit-react'; +import Link from 'next/link'; +import { usePathname } from 'next/navigation'; +import { useEffect, useRef, useState } from 'react'; +import { useForm } from 'react-hook-form'; +import Swal from 'sweetalert2'; +import withReactContent from 'sweetalert2-react-content'; +import * as z from "zod"; + +const articleSchema = z.object({ + title: z.string().min(1, { message: "Required" }), + article: z.string().min(1, { message: "Required" }), + slug: z.string().min(1, { message: "Required" }), + tags: z.string().min(0, { message: "Required" }).optional(), + description: z.string().min(1, { message: "Required" }).optional(), + +}); + +export default function FormUpdateArticle() { + // const [id, setId] = useState(); + const [title, setTitle] = useState(""); + const [slug, setSlug] = useState(""); + const [tags, setTags] = useState([]); + const [newTags, setNewTags] = useState(""); + const editor = useRef(null); + const [content, setContent] = useState(''); + const MySwal = withReactContent(Swal); + const [article, setArticle] = useState(); + const pathname = usePathname(); + const splitPathname = pathname.split('/'); + const id = splitPathname[splitPathname.length - 1]; + console.log(id, "pathnamesplit") + + const formOptions = { resolver: zodResolver(articleSchema) }; + type MicroIssueSchema = z.infer; + const { + register, + control, + handleSubmit, + setValue, + formState: { errors }, + } = useForm(formOptions); + + const editorConfig = { + readonly: true, + } + + const TypeId = [ + { + key: 1, + label: "Article" + }, + { + key: 2, + label: "Magazine" + }, + ] + + const CategoryArticle = [ + { + key: 1, + label: "Article" + }, + { + key: 2, + label: "Magazine" + }, + ] + + const handleClose = (tagsToRemove: string) => { + setTags(tags.filter((tag) => tag !== tagsToRemove)); + if (tags.length === 1) { + setTags([]); + } + }; + + const handleAddTags = (e: any) => { + if (newTags.trim() !== "") { + setTags([...tags, newTags.trim()]); + setNewTags(""); + e.preventDefault(); + } + }; + + const handleKeyDown = (event: any) => { + if (event.key === "Enter") { + handleAddTags(event); + } + }; + + + useEffect(() => { + async function initState() { + const res = await getArticleById(id); + setArticle(res.data?.data); + setTitle(res.data?.data?.title) + console.log("Data Aritcle", res.data?.data); + } + + initState(); + }, []); + + + async function save(data: any,) { + const formData = { + id: id, + title: title, + typeId: parseInt(String(Array.from(article)[0])), + slug: slug, + tags: tags.join(','), + description: content, + htmlDescription: content + }; + + console.log("Form Data:", formData); + // const response = await createArticle(formData); + + // if (response?.error) { + // error(response.message); + // return false; + // } + }; + + async function onSubmit(data: any) { + MySwal.fire({ + title: "Simpan Data", + text: "", + icon: "warning", + showCancelButton: true, + cancelButtonColor: "#d33", + confirmButtonColor: "#3085d6", + confirmButtonText: "Simpan", + }).then((result) => { + if (result.isConfirmed) { + save(data); + } + }); + } + return ( +
+
+ +
+ +
+ {(title?.length === 0 && errors.title) && errors.title.message} + +
+
+
+ +
+ {errors.article?.message} +
+ {/*

{article}

*/} +
+
+ setSlug(e.target.value)} + label="Slug" + variant='bordered' + placeholder="Enter Text" + labelPlacement='outside' + /> +
+ {(slug.length === 0 && errors.slug) && errors.slug.message} +
+
+
+

Tags

+ {/* setNewTags(e.target.value)} + onKeyDown={handleKeyDown} + placeholder="Tambahkan tag baru dan tekan Enter" + /> */} +
+ {(tags.length === 0 && errors.tags) && errors.tags.message} +
+
+ handleClose("close")}> + {article?.tags} + +
+
+
+

Description

+ setContent(newContent)} + className="dark:text-black" + + /> +
+ {(content.length === 0 && errors.description) && errors.description.message} +
+
+
+

Attachment (Opsional)

+
+ +
+
+
+ + + + +
+
+
+
+ ) +} diff --git a/components/sidebar/sidebar.tsx b/components/sidebar/sidebar.tsx index d3f5974..d23cbe0 100644 --- a/components/sidebar/sidebar.tsx +++ b/components/sidebar/sidebar.tsx @@ -1,5 +1,5 @@ import { SidebarMenuTask } from "@/types/globals"; -import { Dropdown, DropdownItem, DropdownMenu, DropdownTrigger, Tooltip, User } from '@nextui-org/react'; +import { Tooltip } from '@nextui-org/react'; import Link from 'next/link'; import { usePathname } from 'next/navigation'; import React, { useEffect, useState } from 'react'; @@ -97,7 +97,7 @@ const sideBarDummyData = [ name: "E-Magazine", moduleId: 652, moduleName: "Dashboard", - modulePathUrl: "/admin/pagination-basic", + modulePathUrl: "/admin/e-magazine", parentId: -1, icon: , position: 1, @@ -126,7 +126,7 @@ const sideBarDummyData = [ name: "Master Menu", moduleId: 652, moduleName: "Form Custom", - modulePathUrl: "/admin/form-costum", + modulePathUrl: "/admin/master-menu", parentId: -1, icon: , position: 1, @@ -140,7 +140,7 @@ const sideBarDummyData = [ name: "Master Module", moduleId: 653, moduleName: "Form Horizontal", - modulePathUrl: "/admin/form-horizontal", + modulePathUrl: "/admin/master-module", parentId: -1, icon: , position: 1, @@ -154,7 +154,7 @@ const sideBarDummyData = [ name: "Master User", moduleId: 654, moduleName: "Form Vertical", - modulePathUrl: "/admin/form-vertical", + modulePathUrl: "/admin/master-user", parentId: -1, icon: , position: 1, @@ -168,7 +168,7 @@ const sideBarDummyData = [ name: "Master User Levels", moduleId: 655, moduleName: "Form Layout", - modulePathUrl: "/admin/form-layout", + modulePathUrl: "/admin/master-user-level", parentId: -1, icon: , position: 1, @@ -182,7 +182,7 @@ const sideBarDummyData = [ name: "Master User Role", moduleId: 656, moduleName: "Form Validation", - modulePathUrl: "/admin/form-validation", + modulePathUrl: "/admin/master-user-role", parentId: -1, icon: , position: 1, @@ -311,8 +311,8 @@ const Sidebar: React.FC = ({ updateSidebarData }) => { }
- - {isOpen && ACME} + + {/* {isOpen && ACME} */}
{isOpen && }
-
+ {/*
@@ -359,7 +359,7 @@ const Sidebar: React.FC = ({ updateSidebarData }) => {
-
+
*/} {sideBarDummyData ? sideBarDummyData?.map((list: any, index: number) => ( diff --git a/components/table/article-table.tsx b/components/table/article-table.tsx index 7248b24..634ea4d 100644 --- a/components/table/article-table.tsx +++ b/components/table/article-table.tsx @@ -8,7 +8,8 @@ import { EyeIcon, EyeIconMdi } from "@/components/icons"; -import { getListArticle } from "@/service/article"; +import { error, success, } from "@/config/swal"; +import { deleteArticle, getListArticle } from "@/service/article"; import { Article } from "@/types/globals"; import { Button } from "@nextui-org/button"; import { @@ -29,6 +30,8 @@ import { } from "@nextui-org/react"; import Link from "next/link"; import { Key, useCallback, useEffect, useState } from "react"; +import Swal from "sweetalert2"; +import withReactContent from "sweetalert2-react-content"; type UserObject = { id: number; @@ -46,6 +49,7 @@ const statusColorMap = { export default function ArticleTable() { + const MySwal = withReactContent(Swal); const [article, setArticle] = useState([]); useEffect(() => { @@ -53,11 +57,10 @@ export default function ArticleTable() { const res = await getListArticle(); setArticle(res.data?.data); - console.log("Data Aritcle", res.data.data); + console.log("List Article", res.data.data); } initState(); - }, []); type TableRow = (typeof usersTable)[0]; @@ -70,10 +73,51 @@ export default function ArticleTable() { { name: "Kreator", uid: "creator" }, { name: "Sumber", uid: "source" }, // { name: "Users", uid: "users" }, - { name: "Status", uid: "status" }, + // { name: "Status", uid: "status" }, { name: "Aksi", uid: "actions" }, ]; + + async function doDelete(id: any) { + // loading(); + const resDelete = await deleteArticle(id); + + if (resDelete?.error) { + error(resDelete.message); + return false; + } + close(); + success("Success Deleted"); + } + + const handleDelete = (id: any) => { + MySwal.fire({ + title: "Hapus Data", + icon: "warning", + showCancelButton: true, + cancelButtonColor: "#3085d6", + confirmButtonColor: "#d33", + confirmButtonText: "Hapus", + }).then((result) => { + if (result.isConfirmed) { + doDelete(id); + } + }); + }; + + function successSubmit() { + MySwal.fire({ + title: "Sukses", + icon: "success", + confirmButtonColor: "#3085d6", + confirmButtonText: "OK", + }).then((result) => { + if (result.isConfirmed) { + // initStete(); + } + }); + } + // const statusOptions = [ // { name: "Active", uid: "active" }, // { name: "Paused", uid: "paused" }, @@ -164,7 +208,7 @@ export default function ArticleTable() { > Detail @@ -176,7 +220,8 @@ export default function ArticleTable() { > Edit @@ -184,20 +229,16 @@ export default function ArticleTable() { handleDelete(article.id)} > - - - Delete - + + Delete diff --git a/service/article.ts b/service/article.ts index 57c8ade..874774b 100644 --- a/service/article.ts +++ b/service/article.ts @@ -1,4 +1,5 @@ -import { httpGet, httpPost } from "./http-config/axios-base-service"; +import Head from "next/head"; +import { httpDeleteInterceptor, httpGet, httpPost, httpPut } from "./http-config/axios-base-service"; export async function getListArticle() { const headers = { @@ -8,6 +9,28 @@ export async function getListArticle() { } export async function createArticle(data: any) { + const headers = { + "content-type": "application/json", + }; const pathUrl = `/articles`; - return await httpPost(pathUrl, data); + return await httpPost(pathUrl, headers, data); +} + +export async function updateArticle(id: any) { + const headers = { + "content-type": "application/json", + }; + const pathUrl = `/articles/${id}`; + return await httpPut(pathUrl, headers); +} + +export async function getArticleById(id: any) { + const headers = { + "content-type": "application/json", + }; + return await httpGet(`/articles/${id}`, headers); +} + +export async function deleteArticle(id: string) { + return await httpDeleteInterceptor(`articles/${id}`); } \ No newline at end of file diff --git a/service/http-config/axios-base-service.ts b/service/http-config/axios-base-service.ts index 4d26451..5b938c9 100644 --- a/service/http-config/axios-base-service.ts +++ b/service/http-config/axios-base-service.ts @@ -1,4 +1,5 @@ import axiosBaseInstance from "./http-base-service"; +import mediahubBaseInstance from "./mediahub-base-service"; export async function httpPost(pathUrl: any, headers: any, data?: any) { const response = await axiosBaseInstance @@ -46,3 +47,69 @@ export async function httpGet(pathUrl: any, headers: any) { } } +export async function httpPut(pathUrl: any, headers: any, data?: any) { + const response = await axiosBaseInstance + .put(pathUrl, data, { headers }) + .catch(function (error: any) { + console.log(error); + return error.response; + }); + console.log("Response base svc : ", response); + if (response?.status == 200 || response?.status == 201) { + return { + error: false, + message: "success", + data: response?.data, + }; + } else { + return { + error: true, + message: response?.data?.message || response?.data || null, + data: null, + }; + } +} + +export async function httpDeleteInterceptor(pathUrl: any) { + const response = await axiosBaseInstance + .delete(pathUrl) + .catch((error) => error.response); + console.log("Response interceptor : ", response); + if (response?.status == 200 || response?.status == 201) { + return { + error: false, + message: "success", + data: response?.data, + }; + } else { + return { + error: true, + message: response?.data?.message || response?.data || null, + data: null, + }; + } +} + + +export async function mediahubGet(pathUrl: any, headers: any) { + const response = await mediahubBaseInstance + .get(pathUrl, { headers }) + .catch(function (error: any) { + console.log(error); + return error.response; + }); + console.log("Response base svc : ", response); + if (response?.status == 200 || response?.status == 201) { + return { + error: false, + message: "success", + data: response?.data, + }; + } else { + return { + error: true, + message: response?.data?.message || response?.data || null, + data: null, + }; + } +} diff --git a/service/http-config/mediahub-base-service.ts b/service/http-config/mediahub-base-service.ts new file mode 100644 index 0000000..499c570 --- /dev/null +++ b/service/http-config/mediahub-base-service.ts @@ -0,0 +1,12 @@ +import axios from "axios"; + +const baseURL = "https://mediahub.polri.go.id/api"; + +const mediahubBaseInstance = axios.create({ + baseURL, + headers: { + "content-type": "application/json", + }, +}); + +export default mediahubBaseInstance; diff --git a/service/medol-news-update.ts b/service/medol-news-update.ts new file mode 100644 index 0000000..8f6ee77 --- /dev/null +++ b/service/medol-news-update.ts @@ -0,0 +1,8 @@ +import { mediahubGet } from "./http-config/axios-base-service"; + +export async function top5NewsMediahub() { + const headers = { + "content-type": "application/json", + }; + return await mediahubGet(`/media/public/list?enablePage=1&sort=desc&sortBy=createdAt&size=5&page=0&typeId=1&title=&categoryId=&fileFormats=&tags=&group=&startDate=&endDate=&month=&year=`, headers); +} \ No newline at end of file diff --git a/styles/globals.css b/styles/globals.css index 62aae12..e419463 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -33,3 +33,4 @@ .sidebar-scrollbar { --scroll-shadow-size: 40px; } + From 2d82441c159158799d1bd0c6a00fa3e850dc4dfe Mon Sep 17 00:00:00 2001 From: amd123 Date: Wed, 24 Apr 2024 17:10:26 +0700 Subject: [PATCH 02/25] feat: masteruser --- .../admin/(basic-form)/form-costum/page.tsx | 30 -- .../(basic-form)/form-horizontal/page.tsx | 38 -- .../admin/(basic-form)/form-layout/page.tsx | 40 -- .../(basic-form)/form-validation/page.tsx | 37 -- .../admin/(basic-form)/form-vertical/page.tsx | 30 -- .../admin/(basic-form)/form-wizard/page.tsx | 44 --- app/(admin)/admin/basic/page.tsx | 39 -- app/(admin)/admin/master-user/create/page.tsx | 10 + app/(admin)/admin/master-user/page.tsx | 24 ++ app/(admin)/admin/menu1/submenu1/page.tsx | 8 - app/(admin)/admin/menu1/submenu2/page.tsx | 8 - components/form/form-article.tsx | 19 +- components/form/form-master-user.tsx | 348 ++++++++++++++++++ components/table/article-table.tsx | 6 +- components/table/master-user-table.tsx | 296 +++++++++++++++ service/article.ts | 1 - service/master-user.ts | 20 + types/globals.tsx | 18 + 18 files changed, 726 insertions(+), 290 deletions(-) delete mode 100644 app/(admin)/admin/(basic-form)/form-costum/page.tsx delete mode 100644 app/(admin)/admin/(basic-form)/form-horizontal/page.tsx delete mode 100644 app/(admin)/admin/(basic-form)/form-layout/page.tsx delete mode 100644 app/(admin)/admin/(basic-form)/form-validation/page.tsx delete mode 100644 app/(admin)/admin/(basic-form)/form-vertical/page.tsx delete mode 100644 app/(admin)/admin/(basic-form)/form-wizard/page.tsx delete mode 100644 app/(admin)/admin/basic/page.tsx create mode 100644 app/(admin)/admin/master-user/create/page.tsx create mode 100644 app/(admin)/admin/master-user/page.tsx delete mode 100644 app/(admin)/admin/menu1/submenu1/page.tsx delete mode 100644 app/(admin)/admin/menu1/submenu2/page.tsx create mode 100644 components/form/form-master-user.tsx create mode 100644 components/table/master-user-table.tsx create mode 100644 service/master-user.ts diff --git a/app/(admin)/admin/(basic-form)/form-costum/page.tsx b/app/(admin)/admin/(basic-form)/form-costum/page.tsx deleted file mode 100644 index 224d54c..0000000 --- a/app/(admin)/admin/(basic-form)/form-costum/page.tsx +++ /dev/null @@ -1,30 +0,0 @@ -"use client" -import { Image } from "@nextui-org/react"; - -export default function CustumPage() { - return ( -
-
-
-
- -
-
-

Custum Form

-

custom designed elemnt

-
-
- NextUI hero Image -
-
-
-
- {/* */} -
-
- ); -} diff --git a/app/(admin)/admin/(basic-form)/form-horizontal/page.tsx b/app/(admin)/admin/(basic-form)/form-horizontal/page.tsx deleted file mode 100644 index 63b5dc8..0000000 --- a/app/(admin)/admin/(basic-form)/form-horizontal/page.tsx +++ /dev/null @@ -1,38 +0,0 @@ -"use client" -import CreateCustomForm from "@/components/form/form-costum/custom-form"; -import CreateHorizontalForm from "@/components/form/form-horizontal/custom-form"; -import CreateWizardForm from "@/components/form/form-wizard/wizard-form"; -import AuthtorsTable from "@/components/table/authors-table"; -import CustomerTable from "@/components/table/customers-table"; -import InvoiceTable from "@/components/table/invoice-table"; -import UserTable from "@/components/table/article-table"; -import UsersTable from "@/components/table/users-table"; -import { Card, Divider, Image } from "@nextui-org/react"; - -export default function HorizontalPage() { - return ( -
-
-
-
- -
-
-

Horizontal Form

-

Home{" > "} Horizontal Form

-
-
- NextUI hero Image -
-
-
-
- -
-
- ); -} diff --git a/app/(admin)/admin/(basic-form)/form-layout/page.tsx b/app/(admin)/admin/(basic-form)/form-layout/page.tsx deleted file mode 100644 index 74c70ca..0000000 --- a/app/(admin)/admin/(basic-form)/form-layout/page.tsx +++ /dev/null @@ -1,40 +0,0 @@ -"use client" - -import CreateLayoutForm from "@/components/form/form-layout/layout-form"; -import CreateValidationForm from "@/components/form/form-validation/validation-form"; -import CreateWizardForm from "@/components/form/form-wizard/wizard-form"; -import AuthtorsTable from "@/components/table/authors-table"; -import CustomerTable from "@/components/table/customers-table"; -import InvoiceTable from "@/components/table/invoice-table"; -import UserTable from "@/components/table/article-table"; -import UsersTable from "@/components/table/users-table"; -import { Card, Divider, Image } from "@nextui-org/react"; -import { useEffect, useState } from "react"; - -export default function FormLayoutPage() { - - return ( -
-
-
-
-
-
-

Form Layout

-

Home{" > "} Form Layout

-
-
- NextUI hero Image -
-
-
-
- -
-
- ); -} diff --git a/app/(admin)/admin/(basic-form)/form-validation/page.tsx b/app/(admin)/admin/(basic-form)/form-validation/page.tsx deleted file mode 100644 index 8480b7e..0000000 --- a/app/(admin)/admin/(basic-form)/form-validation/page.tsx +++ /dev/null @@ -1,37 +0,0 @@ -"use client" -import CreateValidationForm from "@/components/form/form-validation/validation-form"; -import CreateWizardForm from "@/components/form/form-wizard/wizard-form"; -import AuthtorsTable from "@/components/table/authors-table"; -import CustomerTable from "@/components/table/customers-table"; -import InvoiceTable from "@/components/table/invoice-table"; -import UserTable from "@/components/table/article-table"; -import UsersTable from "@/components/table/users-table"; -import { Card, Divider, Image } from "@nextui-org/react"; - -export default function ValidationPage() { - return ( -
-
-
-
- -
-
-

Form Validation

-

Home{" > "} Form Validation

-
-
- NextUI hero Image -
-
-
-
- -
-
- ); -} diff --git a/app/(admin)/admin/(basic-form)/form-vertical/page.tsx b/app/(admin)/admin/(basic-form)/form-vertical/page.tsx deleted file mode 100644 index 61ca9f4..0000000 --- a/app/(admin)/admin/(basic-form)/form-vertical/page.tsx +++ /dev/null @@ -1,30 +0,0 @@ -"use client" -import { Image } from "@nextui-org/react"; - -export default function VerticalPage() { - return ( -
-
-
-
- -
-
-

Vertical Form

-

Home{" > "} Verical Form

-
-
- NextUI hero Image -
-
-
-
- {/* */} -
-
- ); -} diff --git a/app/(admin)/admin/(basic-form)/form-wizard/page.tsx b/app/(admin)/admin/(basic-form)/form-wizard/page.tsx deleted file mode 100644 index b096f16..0000000 --- a/app/(admin)/admin/(basic-form)/form-wizard/page.tsx +++ /dev/null @@ -1,44 +0,0 @@ -"use client" -import CreateWizardForm from "@/components/form/form-wizard/wizard-form"; -import AuthtorsTable from "@/components/table/authors-table"; -import CustomerTable from "@/components/table/customers-table"; -import InvoiceTable from "@/components/table/invoice-table"; -import UserTable from "@/components/table/article-table"; -import UsersTable from "@/components/table/users-table"; -import { Card, Divider, Image } from "@nextui-org/react"; - -export default function WizardPage() { - return ( -
-
-
-
- -
-
-

Form Wizard

-

This is Form WizardPage

-
-
- NextUI hero Image -
-
-
-
- -

Form Wizard

- -
- -
- - -
-
-
- ); -} diff --git a/app/(admin)/admin/basic/page.tsx b/app/(admin)/admin/basic/page.tsx deleted file mode 100644 index f9d5058..0000000 --- a/app/(admin)/admin/basic/page.tsx +++ /dev/null @@ -1,39 +0,0 @@ -"use client" -import { Card, Divider, Image } from "@nextui-org/react"; - -export default function BasicPage() { - return ( -
-
-
-
-
-
-

Basic Table

-

Home{" > "} Basic Table

-
-
- NextUI hero Image -
-
-
-
- -

Basic Table

- -
- {/* - - - - */} -
-
-
-
- ); -} diff --git a/app/(admin)/admin/master-user/create/page.tsx b/app/(admin)/admin/master-user/create/page.tsx new file mode 100644 index 0000000..a345e3c --- /dev/null +++ b/app/(admin)/admin/master-user/create/page.tsx @@ -0,0 +1,10 @@ +import FormMasterUser from '@/components/form/form-master-user' +import { Card } from '@nextui-org/react' + +export default function CreateMasterUserPage() { + return ( + + + + ) +} diff --git a/app/(admin)/admin/master-user/page.tsx b/app/(admin)/admin/master-user/page.tsx new file mode 100644 index 0000000..81372a0 --- /dev/null +++ b/app/(admin)/admin/master-user/page.tsx @@ -0,0 +1,24 @@ +"use client" +import { AddIcon } from "@/components/icons"; +import MasterUserTable from "@/components/table/master-user-table"; +import { Button, Card } from "@nextui-org/react"; +import Link from "next/link"; + +export default function MasterUserPage() { + return ( +
+
+ + + + + + + + +
+
+ ); +} diff --git a/app/(admin)/admin/menu1/submenu1/page.tsx b/app/(admin)/admin/menu1/submenu1/page.tsx deleted file mode 100644 index e87ac7f..0000000 --- a/app/(admin)/admin/menu1/submenu1/page.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { ThemeSwitch } from "@/components/theme-switch"; - -export default function Submenu1Page() { - return ( -
Submenu1 -
- ) -} \ No newline at end of file diff --git a/app/(admin)/admin/menu1/submenu2/page.tsx b/app/(admin)/admin/menu1/submenu2/page.tsx deleted file mode 100644 index 648391b..0000000 --- a/app/(admin)/admin/menu1/submenu2/page.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { ThemeSwitch } from "@/components/theme-switch"; - -export default function Submenu2Page() { - return ( -
Submenu2 -
- ) -} \ No newline at end of file diff --git a/components/form/form-article.tsx b/components/form/form-article.tsx index d36f28b..b024a95 100644 --- a/components/form/form-article.tsx +++ b/components/form/form-article.tsx @@ -1,16 +1,16 @@ 'use client' -import { Button, Card, Chip, Input, Select, SelectItem, Selection } from '@nextui-org/react' +import { error } from '@/config/swal'; +import { createArticle } from '@/service/article'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { Button, Card, Chip, Input, Select, SelectItem, Selection } from '@nextui-org/react'; import JoditEditor from 'jodit-react'; -import React, { ChangeEvent, useRef, useState } from 'react' -import * as z from "zod"; +import Link from 'next/link'; +import { useRouter } from 'next/navigation'; +import React, { ChangeEvent, useRef, useState } from 'react'; +import { useForm } from 'react-hook-form'; import Swal from 'sweetalert2'; import withReactContent from 'sweetalert2-react-content'; -import { useForm } from 'react-hook-form'; -import { zodResolver } from '@hookform/resolvers/zod'; -import { createArticle } from '@/service/article'; -import { error } from '@/config/swal'; -import { useRouter } from 'next/navigation'; -import Link from 'next/link'; +import * as z from "zod"; const articleSchema = z.object({ title: z.string().min(1, { message: "Required" }), @@ -23,7 +23,6 @@ const articleSchema = z.object({ export default function FormArticle() { const router = useRouter(); - const [id, setId] = useState(); const [title, setTitle] = useState(""); const [article, setArticle] = React.useState(new Set([])); const [slug, setSlug] = useState(""); diff --git a/components/form/form-master-user.tsx b/components/form/form-master-user.tsx new file mode 100644 index 0000000..6460f1d --- /dev/null +++ b/components/form/form-master-user.tsx @@ -0,0 +1,348 @@ +'use client' +import { error } from '@/config/swal'; +import { createMasterUser } from '@/service/master-user'; +import { MasterUser } from '@/types/globals'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { Button, Card, Input, Radio, RadioGroup, Select, SelectItem, Selection, Textarea } from '@nextui-org/react' +import Link from 'next/link'; +import { useRouter } from 'next/navigation'; +import React, { useState } from 'react' +import { useForm } from 'react-hook-form'; +import Swal from 'sweetalert2'; +import withReactContent from 'sweetalert2-react-content'; +import { z } from 'zod'; + +const masterUserSchema = z.object({ + fullname: z.string().min(1, { message: "Required" }), + username: z.string().min(1, { message: "Required" }), + email: z.string().min(1, { message: "Required" }), + identityType: z.string().min(1, { message: "Required" }), + lastEducation: z.string().min(1, { message: "Required" }), + phoneNumber: z.string().min(1, { message: "Required" }), + workingType: z.string().min(1, { message: "Required" }), +}); + +export default function FormMasterUser() { + const router = useRouter(); + const MySwal = withReactContent(Swal); + const [address, setAddress] = useState(); + const [dateOfBirt, setDateOfBirt] = useState("13-april-1995"); + const [email, setEmail] = useState(); + const [fullName, setFullname] = useState(); + const [genderType, setGenderType] = React.useState(""); + const [identityNumber, setIdentityNumber] = useState(); + const [lastEducation, setLastEducation] = useState([]); + const [phoneNumber, setPhoneNumber] = useState(); + const [userLevelsId, setUserLevelsId] = useState(1); + const [userRoleId, setUserRoleId] = useState(1); + const [username, setUsername] = useState(); + const [workType, setWorkType] = useState("Tets"); + const [identityType, setIdentityType] = useState([]) + const [showNumberInput, setShowNumberInput] = useState(false); + + const formOptions = { resolver: zodResolver(masterUserSchema) }; + type MicroIssueSchema = z.infer; + const { + register, + control, + handleSubmit, + setValue, + formState: { errors }, + } = useForm(formOptions); + + const typeIdentity = [ + { + id: 1, + value: "KTP", + }, + { + id: 2, + value: "SIM", + }, + { + id: 3, + value: "Passport", + }, + ] + + const workingBackground = [ + { + id: 1, + value: "Pegawai Negri Sipil", + }, + { + id: 2, + value: "Wiraswasta", + }, + { + id: 3, + value: "Guru", + }, + { + id: 4, + value: "Dokter", + }, + ] + + const educationGrade = [ + { + id: 1, + value: "SMA / Sederajat", + }, + { + id: 2, + value: "Diploma 1", + }, + { + id: 3, + value: "Diploma 2", + }, + { + id: 4, + value: "Diploma 3", + }, + { + id: 5, + value: "Diploma 4", + }, + { + id: 6, + value: "S1", + }, + { + id: 7, + value: "S2", + }, + { + id: 8, + value: "S3", + }, + ] + + + async function save(data: any) { + const formData = { + address: address, + dateOfBirt: dateOfBirt, + email: email, + fullName: fullName, + genderType: genderType, + identityNumber: identityNumber, + identityType: identityType.anchorKey, + lastEducation: Array.from(lastEducation)[0], + phoneNumber: phoneNumber, + userLevelsId: userLevelsId, + userRoleId: userRoleId, + username: username, + workType: workType, + }; + + console.log("Form MasterUser:", formData); + const response = await createMasterUser(formData); + + if (response?.error) { + error(response.message); + return false; + } + + successSubmit("/admin/article"); + }; + + function successSubmit(redirect: any) { + MySwal.fire({ + title: "Sukses", + icon: "success", + confirmButtonColor: "#3085d6", + confirmButtonText: "OK", + }).then((result) => { + if (result.isConfirmed) { + router.push(redirect); + } + }); + } + + async function onSubmit(data: any) { + MySwal.fire({ + title: "Simpan Data", + text: "", + icon: "warning", + showCancelButton: true, + cancelButtonColor: "#d33", + confirmButtonColor: "#3085d6", + confirmButtonText: "Simpan", + }).then((result) => { + if (result.isConfirmed) { + save(data); + } + }); + } + + return ( +
+
+ +
+ setFullname(e.target.value)} + /> + {errors.fullname?.message} +
+
+ setUsername(e.target.value)} + + /> + {errors.username?.message} +
+
+ setEmail(e.target.value)} + /> + {errors.email?.message} +
+
+ + {/*

selected : {identityType}

*/} + {errors.identityType?.message} + {/* {showNumberInput && ( */} + setIdentityNumber(e.target.value)} + /> + {/* )} */} +
+
+ + Laki-laki + Perempuan + +

Selected: {genderType}

+
+
+ +

Selected: {lastEducation}

+ {errors.lastEducation?.message} +
+
+ setPhoneNumber(e.target.value)} + /> + {errors.phoneNumber?.message} +
+
+ + {errors.workingType?.message} +
+
+