This commit is contained in:
amd123 2024-04-24 11:14:06 +07:00
parent a6c22e392a
commit c36cc8f0aa
15 changed files with 928 additions and 82 deletions

View File

@ -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 (
<div className="flex h-[96vh] overflow-x-hidden overflow-y-scroll gap-0 grid rounded-lg border-small ml-4">
<div className="flex h-[96vh] overflow-x-hidden overflow-y-scroll gap-0 rounded-lg border-small ml-4">
<div className="px-4">
<div className="bg-blue-900 mx-[24px] h-[120px] my-5 rounded-md">
<div>
@ -25,7 +23,7 @@ export default function VerticalPage() {
</div>
</div>
</div >
<CreateVerticalForm />
{/* <CreateVerticalForm /> */}
</div>
</div>
);

View File

@ -0,0 +1,10 @@
import FormDetailArticle from '@/components/form/form-detail-article'
import { Card } from '@nextui-org/react'
export default function DetailArticlePage() {
return (
<Card className="h-[96vh] rounded-md my- ml-3 border bg-transparent">
<FormDetailArticle />
</Card>
)
}

View File

@ -0,0 +1,10 @@
import FormUpdateArticle from '@/components/form/form-edit-article'
import { Card } from '@nextui-org/react'
export default function UpdateArticlePage() {
return (
<Card className="h-[96vh] rounded-md my- ml-3 border bg-transparent">
<FormUpdateArticle />
</Card>
)
}

View File

@ -0,0 +1,7 @@
import React from 'react'
export default function MasterMenuPage() {
return (
<div>MasterMenuPage</div>
)
}

View File

@ -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<any>();
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) => (
<SwiperSlide>
<Card shadow="sm" className=' bg-white text-black border-2'>
<CardBody className="overflow-visible p-0">
<Image
radius="lg"
width="300%"
alt="tes"
className="object-cover h-[270px]"
src={newsItem.image}
/>
</CardBody>
<CardFooter className="flex flex-col items-start text-left">
<p className='text-xs'>02-04-2024 09:31 WITA</p>
<b className=''>Peringatan Nuzulul Quran, Kapolda Sulbar Harap Kegiatan Ini Tambah Wawasan dan</b>
</CardFooter>
</Card>
<Link href={newsItem?.pageUrl} target='_blank'>
<Card isPressable shadow="sm" className=' bg-white text-black border-2'>
<CardBody className="overflow-visible p-0">
<Image
radius="lg"
width="300%"
alt="tes"
className="object-cover h-[270px]"
src={newsItem.thumbnailLink}
/>
</CardBody>
<CardFooter className="flex flex-col items-start text-left">
<p className='text-xs'>02-04-2024 09:31 WITA</p>
<b className=''>{newsItem?.title}</b>
</CardFooter>
</Card>
</Link>
</SwiperSlide>
))}
</Swiper>

View File

@ -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<any>();
const [title, setTitle] = useState<string>("");
const [article, setArticle] = React.useState<Selection>(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<File[]>([]);
const formOptions = { resolver: zodResolver(articleSchema) };
type MicroIssueSchema = z.infer<typeof articleSchema>;
@ -51,16 +55,29 @@ export default function FormArticle() {
},
]
const CategoryArticle = [
{
key: 1,
label: "Article"
},
{
key: 2,
label: "Magazine"
},
]
const handleImageChange = (event: ChangeEvent<HTMLInputElement>) => {
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() {
</span>
</p>
</div>
<input id="dropzone-file" type="file" />
<input id="dropzone-file" type="file" onChange={handleImageChange} />
</label>
</div>
{
selectedImages?.length > 0 ?
<div>
<h4>Pratinjau:</h4>
<div className='flex gap-2 pt-2'>
{selectedImages.map((image, index) => (
<div key={index} className='flex flex-col items-end'>
<Chip
color='danger'
size='sm'
className='cursor-pointer'
onClick={() => handleRemoveImage(index)}
>
X
</Chip>
<img
src={URL.createObjectURL(image)}
alt="Pratinjau Gambar"
style={{ maxWidth: '200px', maxHeight: '200px' }}
/>
</div>
))}
</div>
</div>
: ""
}
</div>
<div className='flex justify-end gap-3'>
<Link href={`/admin/article`}>
<Button
color='danger'
variant="ghost"
>
Cancel
</Button>
</Link>
<Button
type="submit"
color='primary'
variant="solid"
>
Save
</Button>
</div>
<Button
type="submit"
variant="solid"
className="bg-gradient-to-t from-[#8E5C18] to-[#DBC17B] rounded-md text-white lg:mr-14"
>
Save Data
</Button>
</Card>
</form>
</div>

View File

@ -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<any>();
const [title, setTitle] = useState<string>("");
const [slug, setSlug] = useState<string>("");
const [tags, setTags] = useState<string[]>([]);
const [newTags, setNewTags] = useState<string>("");
const editor = useRef(null);
const [content, setContent] = useState('');
const MySwal = withReactContent(Swal);
const [article, setArticle] = useState<any>();
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<typeof articleSchema>;
const {
register,
control,
handleSubmit,
setValue,
formState: { errors },
} = useForm<MicroIssueSchema>(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 (
<div className='mx-5 my-5 overflow-y-auto'>
<form method="POST" onSubmit={handleSubmit(onSubmit)}>
<Card className='rounded-md p-5 space-y-5'>
<div>
<Input
type="title"
{...register("title")}
isReadOnly
value={title}
onValueChange={setTitle}
label="Judul"
variant='bordered'
placeholder="Enter Text"
labelPlacement='outside'
/>
<div className="text-sm text-red-500">
{(title.length === 0 && errors.title) && errors.title.message}
</div>
</div>
<div>
<Select
label="Jenis Artikel"
{...register("article")}
value={article?.type_id}
variant="bordered"
labelPlacement='outside'
placeholder="Select"
// selectedKeys={article}
className="max-w-xs"
// onSelectionChange={setArticle}
>
{TypeId.map((data) => (
<SelectItem key={data.key} value={data.key}>
{data.label}
</SelectItem>
))}
</Select>
<div className="text-sm text-red-500">
{errors.article?.message}
</div>
{/* <p>{article}</p> */}
</div>
<div>
<Input
isReadOnly
type="text"
{...register("slug")}
value={article?.slug}
onChange={(e) => setSlug(e.target.value)}
label="Slug"
variant='bordered'
placeholder="Enter Text"
labelPlacement='outside'
/>
<div className="text-sm text-red-500">
{(slug.length === 0 && errors.slug) && errors.slug.message}
</div>
</div>
<div>
<p className='text-sm'>Tags</p>
{/* <Input
label="Tags (Optional)"
{...register("tags")}
labelPlacement='outside'
type="text"
value={newTags}
onChange={(e) => setNewTags(e.target.value)}
onKeyDown={handleKeyDown}
placeholder="Tambahkan tag baru dan tekan Enter"
/> */}
<div className="text-sm text-red-500">
{(tags.length === 0 && errors.tags) && errors.tags.message}
</div>
<div className="flex gap-2 border border-inherit mt-2 rounded-md p-1 items-center h-11">
<Chip color='primary' onClose={() => handleClose("close")}>
{article?.tags}
</Chip>
</div>
</div>
<div>
<p className='pb-2'>Description</p>
<JoditEditor
ref={editor}
value={article?.description}
// config={editorConfig}
onChange={(newContent) => setContent(newContent)}
className="dark:text-black"
/>
<div className="text-sm text-red-500">
{(content.length === 0 && errors.description) && errors.description.message}
</div>
</div>
<div>
<p>Attachment (Opsional)</p>
<div className="flex items-center justify-center w-full pt-2 ">
<label
htmlFor="dropzone-file"
className="flex flex-col items-center justify-center w-full h-36 border border-gray-100 border-dashed rounded-lg cursor-pointer bg-gray-50 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:bg-gray-200"
>
<div className="flex flex-col items-center justify-center pt-5 pb-6 ">
<svg
className="w-10 h-10 mb-3 text-gray-400"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
></path>
</svg>
<p className="mb-2 text-sm text-gray-500 dark:text-gray-400">
Drag and drop files here
</p>
<p className="mb-2 text-sm text-gray-500 dark:text-gray-400">
{/* or{" "} */}
<span className="font-semibold underline text-amber-800">
Click to upload
</span>
</p>
</div>
<input id="dropzone-file" type="file" />
</label>
</div>
</div>
<div className='flex justify-end gap-3'>
<Link href={`/admin/article`}>
<Button
color='danger'
variant="ghost"
>
Cancel
</Button>
</Link>
<Button
// type="submit"
color='primary'
variant="solid"
>
Publish
</Button>
</div>
</Card>
</form>
</div>
)
}

View File

@ -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<any>();
const [title, setTitle] = useState<string>("");
const [slug, setSlug] = useState<string>("");
const [tags, setTags] = useState<string[]>([]);
const [newTags, setNewTags] = useState<string>("");
const editor = useRef(null);
const [content, setContent] = useState('');
const MySwal = withReactContent(Swal);
const [article, setArticle] = useState<any>();
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<typeof articleSchema>;
const {
register,
control,
handleSubmit,
setValue,
formState: { errors },
} = useForm<MicroIssueSchema>(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 (
<div className='mx-5 my-5 overflow-y-auto'>
<form method="POST" onSubmit={handleSubmit(onSubmit)}>
<Card className='rounded-md p-5 space-y-5'>
<div>
<Input
type="title"
{...register("title")}
value={title}
onValueChange={setTitle}
label="Judul"
variant='bordered'
placeholder="Enter Text"
labelPlacement='outside'
/>
<div className="text-sm text-red-500">
{(title?.length === 0 && errors.title) && errors.title.message}
</div>
</div>
<div>
<Select
label="Jenis Artikel"
{...register("article")}
value={article?.type_id}
variant="bordered"
labelPlacement='outside'
placeholder="Select"
// selectedKeys={article}
className="max-w-xs"
// onSelectionChange={setArticle}
>
{TypeId.map((data) => (
<SelectItem key={data.key} value={data.key}>
{data.label}
</SelectItem>
))}
</Select>
<div className="text-sm text-red-500">
{errors.article?.message}
</div>
{/* <p>{article}</p> */}
</div>
<div>
<Input
isReadOnly
type="text"
{...register("slug")}
value={article?.slug}
onChange={(e) => setSlug(e.target.value)}
label="Slug"
variant='bordered'
placeholder="Enter Text"
labelPlacement='outside'
/>
<div className="text-sm text-red-500">
{(slug.length === 0 && errors.slug) && errors.slug.message}
</div>
</div>
<div>
<p className='text-sm'>Tags</p>
{/* <Input
label="Tags (Optional)"
{...register("tags")}
labelPlacement='outside'
type="text"
value={newTags}
onChange={(e) => setNewTags(e.target.value)}
onKeyDown={handleKeyDown}
placeholder="Tambahkan tag baru dan tekan Enter"
/> */}
<div className="text-sm text-red-500">
{(tags.length === 0 && errors.tags) && errors.tags.message}
</div>
<div className="flex gap-2 border border-inherit mt-2 rounded-md p-1 items-center h-11">
<Chip color='primary' onClose={() => handleClose("close")}>
{article?.tags}
</Chip>
</div>
</div>
<div>
<p className='pb-2'>Description</p>
<JoditEditor
ref={editor}
value={article?.description}
// config={editorConfig}
onChange={(newContent) => setContent(newContent)}
className="dark:text-black"
/>
<div className="text-sm text-red-500">
{(content.length === 0 && errors.description) && errors.description.message}
</div>
</div>
<div>
<p>Attachment (Opsional)</p>
<div className="flex items-center justify-center w-full pt-2 ">
<label
htmlFor="dropzone-file"
className="flex flex-col items-center justify-center w-full h-36 border border-gray-100 border-dashed rounded-lg cursor-pointer bg-gray-50 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:bg-gray-200"
>
<div className="flex flex-col items-center justify-center pt-5 pb-6 ">
<svg
className="w-10 h-10 mb-3 text-gray-400"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
></path>
</svg>
<p className="mb-2 text-sm text-gray-500 dark:text-gray-400">
Drag and drop files here
</p>
<p className="mb-2 text-sm text-gray-500 dark:text-gray-400">
{/* or{" "} */}
<span className="font-semibold underline text-amber-800">
Click to upload
</span>
</p>
</div>
<input id="dropzone-file" type="file" />
</label>
</div>
</div>
<div className='flex justify-end gap-3'>
<Link href={`/admin/article`}>
<Button
color='danger'
variant="ghost"
>
Cancel
</Button>
</Link>
<Button
type="submit"
color='primary'
variant="solid"
>
Publish
</Button>
</div>
</Card>
</form>
</div>
)
}

View File

@ -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: <TableIcon />,
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: <FormCustomIcon />,
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: <FormHorizontalIcon />,
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: <FormVerticalIcon />,
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: <FormLayoutIcon />,
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: <FormValidationIcon />,
position: 1,
@ -311,8 +311,8 @@ const Sidebar: React.FC<SidebarProps> = ({ updateSidebarData }) => {
}
<div className={`flex ${isOpen ? "justify-between" : "justify-center"} w-full items-center px-2`}>
<div className='flex flex-row items-center gap-3 font-bold'>
<img src="/favicon.ico" className='w-10' />
{isOpen && <span>ACME</span>}
<img src="/logohumas.png" className='w-20' />
{/* {isOpen && <span>ACME</span>} */}
</div>
{isOpen &&
<button
@ -323,7 +323,7 @@ const Sidebar: React.FC<SidebarProps> = ({ updateSidebarData }) => {
</button>
}
</div>
<div className={`flex ${isOpen ? "justify-between" : "justify-center"} w-full items-center px-2 mt-4 mb-4`}>
{/* <div className={`flex ${isOpen ? "justify-between" : "justify-center"} w-full items-center px-2 mt-4 mb-4`}>
<div className='flex flex-row items-center gap-3 font-bold'>
<Dropdown placement="bottom-start">
<DropdownTrigger>
@ -359,7 +359,7 @@ const Sidebar: React.FC<SidebarProps> = ({ updateSidebarData }) => {
</DropdownMenu>
</Dropdown>
</div>
</div>
</div> */}
<SidebarMenu>
{sideBarDummyData
? sideBarDummyData?.map((list: any, index: number) => (

View File

@ -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<Article[]>([]);
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() {
>
<Link
href={`#`}
href={`/admin/article/detail/${article.id}`}
>
<EyeIconMdi className="inline mr-2 mb-1" />
Detail
@ -176,7 +220,8 @@ export default function ArticleTable() {
>
<Link
href={`#`}
href={`/admin/article/edit/${article.id}`}
>
<CreateIconIon className="inline mr-2 mb-1" />
Edit
@ -184,20 +229,16 @@ export default function ArticleTable() {
</DropdownItem>
<DropdownItem
onClick={() => handleDelete(article.id)}
>
<Link
href={`#`}
>
<DeleteIcon
color="red"
width={20}
height={16}
className="inline mr-2 mb-1"
/>
Delete
</Link>
<DeleteIcon
color="red"
width={20}
height={16}
className="inline mr-2 mb-1"
/>
Delete
</DropdownItem>

View File

@ -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}`);
}

View File

@ -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,
};
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -33,3 +33,4 @@
.sidebar-scrollbar {
--scroll-shadow-size: 40px;
}