Merge branch 'main' of https://gitlab.com/hanifsalafi/web-humas-polri into dev-new-ahmad
This commit is contained in:
commit
5881b97109
|
|
@ -0,0 +1,28 @@
|
|||
stages:
|
||||
- build
|
||||
- deploy
|
||||
|
||||
build-dev:
|
||||
stage: build
|
||||
when: on_success
|
||||
only:
|
||||
- main
|
||||
image: docker:stable
|
||||
services:
|
||||
- docker:dind
|
||||
script:
|
||||
- docker logout
|
||||
- docker login -u $DEPLOY_USERNAME -p $DEPLOY_TOKEN registry.gitlab.com
|
||||
- docker build -t registry.gitlab.com/hanifsalafi/web-humas-polri:dev .
|
||||
- docker push registry.gitlab.com/hanifsalafi/web-humas-polri:dev
|
||||
|
||||
auto-deploy:
|
||||
stage: deploy
|
||||
when: on_success
|
||||
only:
|
||||
- main
|
||||
image: curlimages/curl:latest
|
||||
services:
|
||||
- docker:dind
|
||||
script:
|
||||
- curl --user cekmedsos:$JENKINS_PWD http://103.82.242.92:8080/job/autodeploy-humas/build?token=autodeployhumas
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
FROM node:21-alpine
|
||||
|
||||
ENV PORT 4000
|
||||
|
||||
# Create app directory
|
||||
RUN mkdir -p /usr/src/app
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Installing dependencies
|
||||
COPY package*.json /usr/src/app/
|
||||
|
||||
# RUN npm install --force
|
||||
RUN npm install -g npm@latest
|
||||
RUN npm install
|
||||
|
||||
# Copying source files
|
||||
COPY . /usr/src/app
|
||||
|
||||
# Building app
|
||||
RUN npm run build
|
||||
EXPOSE 4000
|
||||
|
||||
# Running the app
|
||||
CMD "npm" "run" "start"
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import CreateMagazineForm from '@/components/form/magazine/magazine-form'
|
||||
import MagazineTable from '@/components/table/magazine/magazine-table'
|
||||
import React from 'react'
|
||||
|
||||
const AdminMagazineCreate = () => {
|
||||
return (
|
||||
<div><CreateMagazineForm /></div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AdminMagazineCreate
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import CreateMagazineForm from '@/components/form/magazine/magazine-form'
|
||||
import MagazineTable from '@/components/table/magazine/magazine-table'
|
||||
import React from 'react'
|
||||
|
||||
const AdminMagazineDetail = () => {
|
||||
return (
|
||||
<div><CreateMagazineForm /></div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AdminMagazineDetail
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import MagazineTable from '@/components/table/magazine/magazine-table'
|
||||
import React from 'react'
|
||||
|
||||
const AdminMagazine = () => {
|
||||
return (
|
||||
<div><MagazineTable /></div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AdminMagazine
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import CreateMagazineForm from '@/components/form/magazine/magazine-form'
|
||||
import CreateMenuDataForm from '@/components/form/master/master-menu/menu-data/menu-data-form'
|
||||
import MagazineTable from '@/components/table/magazine/magazine-table'
|
||||
import React from 'react'
|
||||
|
||||
const AdminMenuDataCreate = () => {
|
||||
return (
|
||||
<div><CreateMenuDataForm /></div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AdminMenuDataCreate
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import MagazineTable from '@/components/table/magazine/magazine-table'
|
||||
import MenuDataTable from '@/components/table/master/master-menu/menu-data/menu-data-table'
|
||||
import React from 'react'
|
||||
|
||||
const AdminMenuData = () => {
|
||||
return (
|
||||
<div><MenuDataTable /></div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AdminMenuData
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import CreateMagazineForm from '@/components/form/magazine/magazine-form'
|
||||
import CreateMenuDataForm from '@/components/form/master/master-menu/menu-data/menu-data-form'
|
||||
import CreateMasterModuleForm from '@/components/form/master/master-module/master-module-form'
|
||||
import MagazineTable from '@/components/table/magazine/magazine-table'
|
||||
import React from 'react'
|
||||
|
||||
const AdminMasterModuleCreate = () => {
|
||||
return (
|
||||
<div><CreateMasterModuleForm /></div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AdminMasterModuleCreate
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import MagazineTable from '@/components/table/magazine/magazine-table'
|
||||
import MenuDataTable from '@/components/table/master/master-menu/menu-data/menu-data-table'
|
||||
import MasterModuleTable from '@/components/table/master/master-module/master-module-table'
|
||||
import React from 'react'
|
||||
|
||||
const AdminMasterModule = () => {
|
||||
return (
|
||||
<div><MasterModuleTable /></div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AdminMasterModule
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import CreateMagazineForm from '@/components/form/magazine/magazine-form'
|
||||
import CreateMenuDataForm from '@/components/form/master/master-menu/menu-data/menu-data-form'
|
||||
import CreateMasterModuleForm from '@/components/form/master/master-module/master-module-form'
|
||||
import CreateMasterUserLevelForm from '@/components/form/master/master-user-level/master-user-level-form'
|
||||
import MagazineTable from '@/components/table/magazine/magazine-table'
|
||||
import React from 'react'
|
||||
|
||||
const AdminMasterUserLevelCreate = () => {
|
||||
return (
|
||||
<div><CreateMasterUserLevelForm /></div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AdminMasterUserLevelCreate
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import MagazineTable from '@/components/table/magazine/magazine-table'
|
||||
import MenuDataTable from '@/components/table/master/master-menu/menu-data/menu-data-table'
|
||||
import MasterModuleTable from '@/components/table/master/master-module/master-module-table'
|
||||
import MasterUserLevelTable from '@/components/table/master/master-user-level/master-user-level-table'
|
||||
import React from 'react'
|
||||
|
||||
const AdminMasterUserLevel = () => {
|
||||
return (
|
||||
<div><MasterUserLevelTable /></div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AdminMasterUserLevel
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import React from 'react'
|
||||
|
||||
export default function AdminHumasPage() {
|
||||
return (
|
||||
<div className=''>
|
||||
<div>1</div>
|
||||
<div>1</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
'use client'
|
||||
import { Button } from "@nextui-org/button";
|
||||
import { Card, Checkbox, CheckboxGroup, Divider, Input, Radio, RadioGroup, Select, SelectItem, Slider, Switch, Tab, Table, Tabs, Textarea, User } from "@nextui-org/react";
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { TimesIcon } from "@/components/icons";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { close, error, loading } from "@/config/swal";
|
||||
import Swal from 'sweetalert2';
|
||||
import withReactContent from 'sweetalert2-react-content';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import parse from 'html-react-parser';
|
||||
|
||||
export default function CreateMagazineForm() {
|
||||
const router = useRouter();
|
||||
const JoditEditor = dynamic(() => import('jodit-react'), { ssr: false });
|
||||
const MySwal = withReactContent(Swal);
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
const [tabs, setTabs] = useState<string>("personal-info")
|
||||
const editor = useRef(null);
|
||||
const [content, setContent] = useState('');
|
||||
const handleTab = (tab: any) => {
|
||||
setTabs(tab);
|
||||
};
|
||||
|
||||
let [files, setFiles] = useState<File[]>([]);
|
||||
|
||||
const removeFile = (name: string) => {
|
||||
const arrayFile: File[] = [];
|
||||
for (const element of files) {
|
||||
if (element.name !== name) {
|
||||
arrayFile.push(element);
|
||||
}
|
||||
}
|
||||
setFiles(arrayFile);
|
||||
};
|
||||
|
||||
const handleFileChange = (event: any) => {
|
||||
const newFiles: FileList | null = event.target.files;
|
||||
if (newFiles) {
|
||||
const allowedExtensions = ['.doc', '.docx', '.pdf', '.ppt', '.pptx', '.xlsx', '.csv'];
|
||||
let temp: File[] = [...files]; // Salin file-file yang sudah ada
|
||||
for (let i = 0; i < newFiles.length; i++) {
|
||||
const file = newFiles[i];
|
||||
const fileExtension = file.name.split('.').pop()?.toLowerCase();
|
||||
if (fileExtension && allowedExtensions.includes(`.${fileExtension}`)) {
|
||||
temp.push(file);
|
||||
} else {
|
||||
alert('Format file tidak valid. Hanya file .doc, .docx, .ppt, .pptx, .xlsx, .csv atau .pdf yang diperbolehkan.');
|
||||
}
|
||||
}
|
||||
setFiles(temp);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleVisibility = () => setIsVisible(!isVisible);
|
||||
|
||||
const validationSchema = z.object({
|
||||
title: z.string().min(1, { message: "Required" }),
|
||||
slug: z.string().min(1, { message: "Required" }),
|
||||
});
|
||||
|
||||
const formOptions = { resolver: zodResolver(validationSchema) };
|
||||
type ArticleSchema = z.infer<typeof validationSchema>;
|
||||
|
||||
const { register, handleSubmit, formState: { errors }, formState, setValue } = useForm<ArticleSchema>(formOptions);
|
||||
|
||||
const save = async (data: any) => {
|
||||
const parsedContent = parse(content);
|
||||
console.log(parsedContent);
|
||||
const request = {
|
||||
title: data.title,
|
||||
slug: data.slug,
|
||||
articleBody: data.articleBody,
|
||||
status: 1,
|
||||
};
|
||||
|
||||
console.log(request);
|
||||
|
||||
// loading();
|
||||
// // const res = await saveManualContext(request);
|
||||
// if (res.error) {
|
||||
// error(res.message);
|
||||
// return false;
|
||||
// }
|
||||
close();
|
||||
successSubmit("/admin/magazine")
|
||||
}
|
||||
|
||||
async function onSubmit(data: any) {
|
||||
MySwal.fire({
|
||||
title: "Save Data",
|
||||
text: "",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
cancelButtonColor: "#d33",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "Save",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
save(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function successSubmit(redirect: string) {
|
||||
MySwal.fire({
|
||||
title: 'Sukses',
|
||||
icon: 'success',
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'OK',
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
router.push(redirect);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx-3 my-5">
|
||||
<div className="flex flex-col gap-3 mb-4">
|
||||
<Card className="w-full bg-white">
|
||||
<div className="w-full mr-2 p-5 ">
|
||||
<form method="POST" onSubmit={handleSubmit(onSubmit)}>
|
||||
<>
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex flex-row justify-between items-center mt-[24px] gap-3">
|
||||
<div className="flex flex-col w-6/12">
|
||||
<Input
|
||||
type="text"
|
||||
label="Title"
|
||||
id="title"
|
||||
{...register("title")}
|
||||
placeholder="...."
|
||||
labelPlacement="outside"
|
||||
className="w-9/12 font-semibold"
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
input: "!text-black hover:!text-white focus:!text-white",
|
||||
inputWrapper: "max-h-[40px] bg-transparant border text-white",
|
||||
}}
|
||||
startContent={
|
||||
<div className="pointer-events-none flex items-center">
|
||||
<span className="text-default-400 text-small"></span>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
{errors.title?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.title?.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col w-6/12">
|
||||
<Input
|
||||
type="text"
|
||||
label="Slug"
|
||||
id="slug"
|
||||
{...register("slug")}
|
||||
placeholder="....."
|
||||
labelPlacement="outside"
|
||||
className="w-9/12 font-semibold"
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
input: "!text-black hover:!text-white focus:!text-white",
|
||||
inputWrapper: "max-h-[40px] bg-transparant border text-white",
|
||||
}}
|
||||
startContent={
|
||||
<div className="pointer-events-none flex items-center">
|
||||
<span className="text-default-400 text-small"></span>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
{errors.slug?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.slug?.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-1">
|
||||
<p className="text-black text-sm font-semibold my-2">Description</p>
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={content}
|
||||
onChange={(newContent) => setContent(newContent)}
|
||||
className="dark:text-black"
|
||||
/>
|
||||
</div>
|
||||
<p className="text-sm text-black mt-2 pb-1 pt-3">Upload File (Opsional)</p>
|
||||
<div className="w-full bg-transparent">
|
||||
<div className="flex items-center justify-center w-full ">
|
||||
<label
|
||||
htmlFor="dropzone-file"
|
||||
className="flex flex-col items-center justify-center w-full h-32 border-2 border-gray-100 border-dashed rounded-lg cursor-pointer bg-gray-50 dark:hover:bg-bray-800 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:bg-gray-600"
|
||||
>
|
||||
<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" multiple accept=".doc,.docx,.pdf,.ppt,.pptx,.xlsx,.csv" className="hidden" onChange={handleFileChange} />
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-tiny text-default ">Support file format in word, excel, ppt and pdf</p>
|
||||
<div className="flex flex-wrap gap-3">
|
||||
{files?.length > 0 &&
|
||||
files?.map((list: File) => (
|
||||
<div key={list.name} className="text-black text-sm py-2 px-4 border-1 border-black w-auto rounded-lg flex justify-between gap-5">
|
||||
{list.name}
|
||||
<a className="cursor-pointer" onClick={() => removeFile(list.name)}><TimesIcon /></a>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
<div className="flex flex-row gap-3 my-3">
|
||||
<Link href="/admin/magazine">
|
||||
<Button
|
||||
variant="bordered"
|
||||
className="bg-white border-grey-100 rounded-full text-[#8E5C18] mr-5"
|
||||
>
|
||||
Cancel
|
||||
</Button>{" "}
|
||||
</Link>
|
||||
<Button
|
||||
className="w-[50px]"
|
||||
color="primary"
|
||||
size="md"
|
||||
type="submit">
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</form>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div >
|
||||
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,397 @@
|
|||
'use client'
|
||||
import { Button } from "@nextui-org/button";
|
||||
import { Card, Checkbox, CheckboxGroup, Divider, Image, Input, Radio, RadioGroup, Select, SelectItem, SelectSection, Slider, Switch, Tab, Table, Tabs, Textarea, User } from "@nextui-org/react";
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { TimesIcon } from "@/components/icons";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { close, error, loading } from "@/config/swal";
|
||||
import Swal from 'sweetalert2';
|
||||
import withReactContent from 'sweetalert2-react-content';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
|
||||
const moduleList = [
|
||||
{ label: "Article", value: "article", id: 1 },
|
||||
{ label: "Caption", value: "caption", id: 2 },
|
||||
{ label: "Meme", value: "meme", id: 3 },
|
||||
{ label: "Video", value: "video", id: 4 },
|
||||
{ label: "Master Data", value: "master-data", id: 5 },
|
||||
];
|
||||
|
||||
export default function CreateMenuDataForm() {
|
||||
const router = useRouter();
|
||||
const JoditEditor = dynamic(() => import('jodit-react'), { ssr: false });
|
||||
const MySwal = withReactContent(Swal);
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
const [tabs, setTabs] = useState<string>("personal-info")
|
||||
const editor = useRef(null);
|
||||
const [content, setContent] = useState('');
|
||||
const [haveChildren, setHaveChildren] = useState("no");
|
||||
const [active, setActive] = useState("1");
|
||||
const handleTab = (tab: any) => {
|
||||
setTabs(tab);
|
||||
};
|
||||
|
||||
const handleActive = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setActive(e.target.value);
|
||||
};
|
||||
|
||||
const handleHaveChildren = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setHaveChildren(e.target.value);
|
||||
};
|
||||
|
||||
let [files, setFiles] = useState<File[]>([]);
|
||||
|
||||
const removeFile = (name: string) => {
|
||||
const arrayFile: File[] = [];
|
||||
for (const element of files) {
|
||||
if (element.name !== name) {
|
||||
arrayFile.push(element);
|
||||
}
|
||||
}
|
||||
setFiles(arrayFile);
|
||||
};
|
||||
|
||||
const handleFileChange = (event: any) => {
|
||||
const newFiles: FileList | null = event.target.files;
|
||||
if (newFiles) {
|
||||
const allowedExtensions = ['.doc', '.docx', '.pdf', '.ppt', '.pptx', '.xlsx', '.csv'];
|
||||
let temp: File[] = [...files]; // Salin file-file yang sudah ada
|
||||
for (let i = 0; i < newFiles.length; i++) {
|
||||
const file = newFiles[i];
|
||||
const fileExtension = file.name.split('.').pop()?.toLowerCase();
|
||||
if (fileExtension && allowedExtensions.includes(`.${fileExtension}`)) {
|
||||
temp.push(file);
|
||||
} else {
|
||||
alert('Format file tidak valid. Hanya file .doc, .docx, .ppt, .pptx, .xlsx, .csv atau .pdf yang diperbolehkan.');
|
||||
}
|
||||
}
|
||||
setFiles(temp);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleVisibility = () => setIsVisible(!isVisible);
|
||||
|
||||
const validationSchema = z.object({
|
||||
name: z.string().min(1, { message: "Required" }),
|
||||
description: z.string().min(1, { message: "Required" }),
|
||||
});
|
||||
|
||||
const formOptions = { resolver: zodResolver(validationSchema) };
|
||||
type ArticleSchema = z.infer<typeof validationSchema>;
|
||||
|
||||
const { register, handleSubmit, formState: { errors }, formState, setValue } = useForm<ArticleSchema>(formOptions);
|
||||
|
||||
const save = async (data: any) => {
|
||||
|
||||
const request = {
|
||||
name: data.name,
|
||||
description: data.description,
|
||||
moduleList: moduleList,
|
||||
status: 1,
|
||||
};
|
||||
|
||||
console.log(request);
|
||||
|
||||
// loading();
|
||||
// // const res = await saveManualContext(request);
|
||||
// if (res.error) {
|
||||
// error(res.message);
|
||||
// return false;
|
||||
// }
|
||||
close();
|
||||
successSubmit("/admin/master/master-menu/menu-data")
|
||||
}
|
||||
|
||||
async function onSubmit(data: any) {
|
||||
MySwal.fire({
|
||||
title: "Save Data",
|
||||
text: "",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
cancelButtonColor: "#d33",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "Save",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
save(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function successSubmit(redirect: string) {
|
||||
MySwal.fire({
|
||||
title: 'Sukses',
|
||||
icon: 'success',
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'OK',
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
router.push(redirect);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx-3 my-5">
|
||||
<div className="flex flex-col gap-3 mb-4">
|
||||
<Card className="w-full bg-white">
|
||||
<div className="w-full mr-2 p-5 ">
|
||||
<form method="POST" onSubmit={handleSubmit(onSubmit)}>
|
||||
<>
|
||||
<div className="flex flex-row gap-1">
|
||||
<div className="w-6/12 justify-start items-start mt-2 gap-3">
|
||||
<div className="flex flex-col ">
|
||||
<Input
|
||||
type="text"
|
||||
label="Name"
|
||||
id="name"
|
||||
{...register("name")}
|
||||
placeholder="Input Name"
|
||||
labelPlacement="outside"
|
||||
className=" font-semibold"
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
input: "!text-black hover:!text-white focus:!text-white",
|
||||
inputWrapper: "max-h-[40px] bg-transparant border text-white",
|
||||
}}
|
||||
startContent={
|
||||
<div className="pointer-events-none flex items-center">
|
||||
<span className="text-default-400 text-small"></span>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
{errors.name?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.name?.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col mt-3">
|
||||
<Input
|
||||
type="text"
|
||||
label="Description"
|
||||
id="description"
|
||||
{...register("description")}
|
||||
placeholder="Input Description"
|
||||
labelPlacement="outside"
|
||||
className=" font-semibold"
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
input: "!text-black hover:!text-white focus:!text-white",
|
||||
inputWrapper: "max-h-[40px] bg-transparant border text-white",
|
||||
}}
|
||||
startContent={
|
||||
<div className="pointer-events-none flex items-center">
|
||||
<span className="text-default-400 text-small"></span>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
{errors.description?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.description?.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-3 ">
|
||||
<p className="text-black text-sm mb-1 font-semibold">Main Module</p>
|
||||
<Select
|
||||
variant="bordered"
|
||||
selectionMode="single"
|
||||
labelPlacement="outside"
|
||||
placeholder="Select"
|
||||
className="font-semibold"
|
||||
items={moduleList}
|
||||
classNames={{
|
||||
mainWrapper: "rounded",
|
||||
listboxWrapper:
|
||||
"bg-white w-full !text-indigo-500 text-center font-bold",
|
||||
popoverContent: "bg-white !text-indigo-500",
|
||||
trigger:
|
||||
"border-1 border-gray-200 hover:!bg-gray-100 !text-black",
|
||||
}}
|
||||
listboxProps={{
|
||||
itemClasses: {
|
||||
base: [
|
||||
"!text-left",
|
||||
"!bg-white",
|
||||
"text-indigo-500 ",
|
||||
"data-[selectable=true]:!text-indigo-500",
|
||||
"data-[pressed=true]:text-indigo-500",
|
||||
"data-[hover=true]:!text-indigo-300",
|
||||
],
|
||||
wrapper: ["!bg-white border-none"],
|
||||
},
|
||||
}}
|
||||
renderValue={(items) => {
|
||||
return items.map((item) => (
|
||||
<span key={item.props?.value} className="text-black text-xs">
|
||||
{item.textValue}
|
||||
</span>
|
||||
));
|
||||
}}
|
||||
>
|
||||
<SelectSection showDivider title="Module">
|
||||
{moduleList.map((list) => (
|
||||
<SelectItem key={list.id} value={list.id}>
|
||||
{list.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectSection>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="text-black mt-3">
|
||||
<label className="text-black text-sm dark:text-black">Have sub module ?</label>
|
||||
<RadioGroup
|
||||
orientation="horizontal"
|
||||
id="radio-banned"
|
||||
className="text-gray-950 pt-2"
|
||||
onChange={handleHaveChildren}
|
||||
defaultValue={haveChildren}
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
description: "!text-black",
|
||||
base: "!text-black",
|
||||
wrapper: "!text-black",
|
||||
}}
|
||||
>
|
||||
<Radio
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
}}
|
||||
value="no"
|
||||
>
|
||||
No
|
||||
</Radio>
|
||||
<Radio
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
}}
|
||||
value="yes"
|
||||
>
|
||||
Yes
|
||||
</Radio>
|
||||
</RadioGroup>
|
||||
</div>
|
||||
{haveChildren === "yes" && (
|
||||
<div className="mt-3 ">
|
||||
<p className="text-black text-sm mb-1 font-semibold">Sub Module</p>
|
||||
<Select
|
||||
variant="bordered"
|
||||
selectionMode="single"
|
||||
labelPlacement="outside"
|
||||
placeholder="Select"
|
||||
className="font-semibold"
|
||||
items={moduleList}
|
||||
classNames={{
|
||||
mainWrapper: "rounded",
|
||||
listboxWrapper:
|
||||
"bg-white w-full !text-indigo-500 text-center font-bold",
|
||||
popoverContent: "bg-white !text-indigo-500",
|
||||
trigger:
|
||||
"border-1 border-gray-200 hover:!bg-gray-100 !text-black",
|
||||
}}
|
||||
listboxProps={{
|
||||
itemClasses: {
|
||||
base: [
|
||||
"!text-left",
|
||||
"!bg-white",
|
||||
"text-indigo-500 ",
|
||||
"data-[selectable=true]:!text-indigo-500",
|
||||
"data-[pressed=true]:text-indigo-500",
|
||||
"data-[hover=true]:!text-indigo-300",
|
||||
],
|
||||
wrapper: ["!bg-white border-none"],
|
||||
},
|
||||
}}
|
||||
renderValue={(items) => {
|
||||
return items.map((item) => (
|
||||
<span key={item.props?.value} className="text-black text-xs">
|
||||
{item.textValue}
|
||||
</span>
|
||||
));
|
||||
}}
|
||||
>
|
||||
<SelectSection showDivider title="Module">
|
||||
{moduleList.map((list) => (
|
||||
<SelectItem key={list.id} value={list.id}>
|
||||
{list.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectSection>
|
||||
</Select>
|
||||
</div>
|
||||
)}
|
||||
<div className="text-black mt-3">
|
||||
<label className="text-black text-sm dark:text-black">Status</label>
|
||||
<RadioGroup
|
||||
orientation="horizontal"
|
||||
id="radio-banned"
|
||||
className="text-gray-950 pt-2"
|
||||
onChange={handleActive}
|
||||
defaultValue={active}
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
description: "!text-black",
|
||||
base: "!text-black",
|
||||
wrapper: "!text-black",
|
||||
}}
|
||||
>
|
||||
<Radio
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
}}
|
||||
value="1"
|
||||
>
|
||||
Active
|
||||
</Radio>
|
||||
<Radio
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
}}
|
||||
value="2"
|
||||
>
|
||||
Inactive
|
||||
</Radio>
|
||||
</RadioGroup>
|
||||
</div>
|
||||
<div className="flex flex-row gap-3 my-3">
|
||||
<Link href="/admin/master/master-menu/menu-data">
|
||||
<Button
|
||||
variant="bordered"
|
||||
className="bg-white border-grey-100 rounded-full text-[#8E5C18] mr-5"
|
||||
>
|
||||
Cancel
|
||||
</Button>{" "}
|
||||
</Link>
|
||||
<Button
|
||||
className="w-[50px]"
|
||||
color="primary"
|
||||
size="md"
|
||||
type="submit">
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-6/12 ">
|
||||
<div className="flex items-center justify-center justify-items-center h-full">
|
||||
<Image
|
||||
width={400}
|
||||
alt="NextUI hero Image"
|
||||
src="/account-category.jpg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</form>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div >
|
||||
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,294 @@
|
|||
'use client'
|
||||
import { Button } from "@nextui-org/button";
|
||||
import { Card, Checkbox, CheckboxGroup, Divider, Image, Input, Radio, RadioGroup, Select, SelectItem, SelectSection, Slider, Switch, Tab, Table, Tabs, Textarea, User } from "@nextui-org/react";
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { TimesIcon } from "@/components/icons";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { close, error, loading } from "@/config/swal";
|
||||
import Swal from 'sweetalert2';
|
||||
import withReactContent from 'sweetalert2-react-content';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
|
||||
const platform = [
|
||||
{ label: "Article", value: "article", id: 1 },
|
||||
{ label: "Caption", value: "caption", id: 2 },
|
||||
{ label: "Meme", value: "meme", id: 3 },
|
||||
{ label: "Video", value: "video", id: 4 },
|
||||
{ label: "Master Data", value: "master-data", id: 5 },
|
||||
];
|
||||
|
||||
export default function CreateMasterModuleForm() {
|
||||
const router = useRouter();
|
||||
const JoditEditor = dynamic(() => import('jodit-react'), { ssr: false });
|
||||
const MySwal = withReactContent(Swal);
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
const [tabs, setTabs] = useState<string>("personal-info")
|
||||
const editor = useRef(null);
|
||||
const [content, setContent] = useState('');
|
||||
const [haveChildren, setHaveChildren] = useState("no");
|
||||
const [active, setActive] = useState("1");
|
||||
const handleTab = (tab: any) => {
|
||||
setTabs(tab);
|
||||
};
|
||||
|
||||
const handleActive = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setActive(e.target.value);
|
||||
};
|
||||
|
||||
const handleHaveChildren = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setHaveChildren(e.target.value);
|
||||
};
|
||||
|
||||
let [files, setFiles] = useState<File[]>([]);
|
||||
|
||||
const removeFile = (name: string) => {
|
||||
const arrayFile: File[] = [];
|
||||
for (const element of files) {
|
||||
if (element.name !== name) {
|
||||
arrayFile.push(element);
|
||||
}
|
||||
}
|
||||
setFiles(arrayFile);
|
||||
};
|
||||
|
||||
const handleFileChange = (event: any) => {
|
||||
const newFiles: FileList | null = event.target.files;
|
||||
if (newFiles) {
|
||||
const allowedExtensions = ['.doc', '.docx', '.pdf', '.ppt', '.pptx', '.xlsx', '.csv'];
|
||||
let temp: File[] = [...files]; // Salin file-file yang sudah ada
|
||||
for (let i = 0; i < newFiles.length; i++) {
|
||||
const file = newFiles[i];
|
||||
const fileExtension = file.name.split('.').pop()?.toLowerCase();
|
||||
if (fileExtension && allowedExtensions.includes(`.${fileExtension}`)) {
|
||||
temp.push(file);
|
||||
} else {
|
||||
alert('Format file tidak valid. Hanya file .doc, .docx, .ppt, .pptx, .xlsx, .csv atau .pdf yang diperbolehkan.');
|
||||
}
|
||||
}
|
||||
setFiles(temp);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleVisibility = () => setIsVisible(!isVisible);
|
||||
|
||||
const validationSchema = z.object({
|
||||
name: z.string().min(1, { message: "Required" }),
|
||||
description: z.string().min(1, { message: "Required" }),
|
||||
pathUrl: z.string().min(1, { message: "Required" }),
|
||||
});
|
||||
|
||||
const formOptions = { resolver: zodResolver(validationSchema) };
|
||||
type ArticleSchema = z.infer<typeof validationSchema>;
|
||||
|
||||
const { register, handleSubmit, formState: { errors }, formState, setValue } = useForm<ArticleSchema>(formOptions);
|
||||
|
||||
const save = async (data: any) => {
|
||||
|
||||
const request = {
|
||||
name: data.name,
|
||||
description: data.description,
|
||||
pathUrl: data.pathUrl,
|
||||
status: 1,
|
||||
};
|
||||
|
||||
console.log(request);
|
||||
// loading();
|
||||
// // const res = await saveManualContext(request);
|
||||
// if (res.error) {
|
||||
// error(res.message);
|
||||
// return false;
|
||||
// }
|
||||
close();
|
||||
successSubmit("/admin/master/master-module")
|
||||
}
|
||||
|
||||
async function onSubmit(data: any) {
|
||||
MySwal.fire({
|
||||
title: "Save Data",
|
||||
text: "",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
cancelButtonColor: "#d33",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "Save",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
save(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function successSubmit(redirect: string) {
|
||||
MySwal.fire({
|
||||
title: 'Sukses',
|
||||
icon: 'success',
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'OK',
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
router.push(redirect);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx-3 my-5">
|
||||
<div className="flex flex-col gap-3 mb-4">
|
||||
<Card className="w-full bg-white">
|
||||
<div className="w-full mr-2 p-5 ">
|
||||
<form method="POST" onSubmit={handleSubmit(onSubmit)}>
|
||||
<>
|
||||
<div className="flex flex-row gap-1">
|
||||
<div className="w-6/12 justify-start items-start mt-2 gap-3">
|
||||
<div className="flex flex-col ">
|
||||
<Input
|
||||
type="text"
|
||||
label="Name"
|
||||
id="name"
|
||||
{...register("name")}
|
||||
placeholder="Input Name"
|
||||
labelPlacement="outside"
|
||||
className=" font-semibold"
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
input: "!text-black hover:!text-white focus:!text-white",
|
||||
inputWrapper: "max-h-[40px] bg-transparant border text-white",
|
||||
}}
|
||||
startContent={
|
||||
<div className="pointer-events-none flex items-center">
|
||||
<span className="text-default-400 text-small"></span>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
{errors.name?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.name?.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col mt-3">
|
||||
<Input
|
||||
type="text"
|
||||
label="Description"
|
||||
id="description"
|
||||
{...register("description")}
|
||||
placeholder="Input Description"
|
||||
labelPlacement="outside"
|
||||
className=" font-semibold"
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
input: "!text-black hover:!text-white focus:!text-white",
|
||||
inputWrapper: "max-h-[40px] bg-transparant border text-white",
|
||||
}}
|
||||
startContent={
|
||||
<div className="pointer-events-none flex items-center">
|
||||
<span className="text-default-400 text-small"></span>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
{errors.description?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.description?.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col mt-3">
|
||||
<Input
|
||||
type="text"
|
||||
label="pathUrl"
|
||||
id="pathUrl"
|
||||
{...register("pathUrl")}
|
||||
placeholder="Input PathUrl"
|
||||
labelPlacement="outside"
|
||||
className=" font-semibold"
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
input: "!text-black hover:!text-white focus:!text-white",
|
||||
inputWrapper: "max-h-[40px] bg-transparant border text-white",
|
||||
}}
|
||||
startContent={
|
||||
<div className="pointer-events-none flex items-center">
|
||||
<span className="text-default-400 text-small"></span>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
{errors.description?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.description?.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-black mt-3">
|
||||
<label className="text-black text-sm dark:text-black">Status</label>
|
||||
<RadioGroup
|
||||
orientation="horizontal"
|
||||
id="radio-banned"
|
||||
className="text-gray-950 pt-2"
|
||||
onChange={handleActive}
|
||||
defaultValue={active}
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
description: "!text-black",
|
||||
base: "!text-black",
|
||||
wrapper: "!text-black",
|
||||
}}
|
||||
>
|
||||
<Radio
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
}}
|
||||
value="1"
|
||||
>
|
||||
Active
|
||||
</Radio>
|
||||
<Radio
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
}}
|
||||
value="2"
|
||||
>
|
||||
Inactive
|
||||
</Radio>
|
||||
</RadioGroup>
|
||||
</div>
|
||||
<div className="flex flex-row gap-3 my-3">
|
||||
<Link href="/admin/master/master-module">
|
||||
<Button
|
||||
variant="bordered"
|
||||
className="bg-white border-grey-100 rounded-full text-[#8E5C18] mr-5"
|
||||
>
|
||||
Cancel
|
||||
</Button>{" "}
|
||||
</Link>
|
||||
<Button
|
||||
className="w-[50px]"
|
||||
color="primary"
|
||||
size="md"
|
||||
type="submit">
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-6/12 ">
|
||||
<div className="flex items-center justify-center justify-items-center h-full">
|
||||
<Image
|
||||
width={400}
|
||||
alt="NextUI hero Image"
|
||||
src="/account-category.jpg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</form>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div >
|
||||
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,413 @@
|
|||
'use client'
|
||||
import { Button } from "@nextui-org/button";
|
||||
import { Card, Checkbox, CheckboxGroup, Divider, Image, Input, Radio, RadioGroup, Select, SelectItem, SelectSection, Slider, Switch, Tab, Table, Tabs, Textarea, User } from "@nextui-org/react";
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { TimesIcon } from "@/components/icons";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { close, error, loading } from "@/config/swal";
|
||||
import Swal from 'sweetalert2';
|
||||
import withReactContent from 'sweetalert2-react-content';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { createUserLevels } from "@/services/user-levels/user-levels-service";
|
||||
|
||||
const LevelList = [
|
||||
{ label: "Admin", value: "admin", id: 1 },
|
||||
{ label: "Super-Admin", value: "super-admin", id: 2 },
|
||||
{ label: "Kurator", value: "kurator", id: 3 },
|
||||
{ label: "Supervisor", value: "supervisor", id: 4 },
|
||||
];
|
||||
|
||||
const moduleList = [
|
||||
{ label: "Article", value: "article", id: 1 },
|
||||
{ label: "Caption", value: "caption", id: 2 },
|
||||
{ label: "Meme", value: "meme", id: 3 },
|
||||
{ label: "Video", value: "video", id: 4 },
|
||||
{ label: "Master Data", value: "master-data", id: 5 },
|
||||
];
|
||||
|
||||
const provinceList = [
|
||||
{ label: "NTT", value: "1", id: 1 },
|
||||
{ label: "NTB", value: "2", id: 2 },
|
||||
{ label: "Aceh", value: "3", id: 3 },
|
||||
{ label: "Jawa Timur", value: "4", id: 4 },
|
||||
{ label: "Jawa Barat", value: "5", id: 5 },
|
||||
];
|
||||
|
||||
export default function CreateMasterUserLevelForm() {
|
||||
const router = useRouter();
|
||||
const JoditEditor = dynamic(() => import('jodit-react'), { ssr: false });
|
||||
const MySwal = withReactContent(Swal);
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
const [tabs, setTabs] = useState<string>("personal-info")
|
||||
const editor = useRef(null);
|
||||
const [content, setContent] = useState('');
|
||||
const [haveChildren, setHaveChildren] = useState("no");
|
||||
const [active, setTrue] = useState("true");
|
||||
const [levelValue, setLevelValue] = useState<any>("");
|
||||
const handleTab = (tab: any) => {
|
||||
setTabs(tab);
|
||||
};
|
||||
|
||||
const handleActive = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setTrue(e.target.value);
|
||||
};
|
||||
|
||||
const handleHaveChildren = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setHaveChildren(e.target.value);
|
||||
};
|
||||
|
||||
let [files, setFiles] = useState<File[]>([]);
|
||||
|
||||
const removeFile = (name: string) => {
|
||||
const arrayFile: File[] = [];
|
||||
for (const element of files) {
|
||||
if (element.name !== name) {
|
||||
arrayFile.push(element);
|
||||
}
|
||||
}
|
||||
setFiles(arrayFile);
|
||||
};
|
||||
|
||||
const handleFileChange = (event: any) => {
|
||||
const newFiles: FileList | null = event.target.files;
|
||||
if (newFiles) {
|
||||
const allowedExtensions = ['.doc', '.docx', '.pdf', '.ppt', '.pptx', '.xlsx', '.csv'];
|
||||
let temp: File[] = [...files]; // Salin file-file yang sudah ada
|
||||
for (let i = 0; i < newFiles.length; i++) {
|
||||
const file = newFiles[i];
|
||||
const fileExtension = file.name.split('.').pop()?.toLowerCase();
|
||||
if (fileExtension && allowedExtensions.includes(`.${fileExtension}`)) {
|
||||
temp.push(file);
|
||||
} else {
|
||||
alert('Format file tidak valid. Hanya file .doc, .docx, .ppt, .pptx, .xlsx, .csv atau .pdf yang diperbolehkan.');
|
||||
}
|
||||
}
|
||||
setFiles(temp);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleVisibility = () => setIsVisible(!isVisible);
|
||||
|
||||
const validationSchema = z.object({
|
||||
name: z.string().min(1, { message: "Required" }),
|
||||
aliasName: z.string().min(1, { message: "Required" }),
|
||||
// levelNumber: z.string().min(1, { message: "Required" }),
|
||||
});
|
||||
|
||||
const formOptions = { resolver: zodResolver(validationSchema) };
|
||||
type ArticleSchema = z.infer<typeof validationSchema>;
|
||||
|
||||
const { register, handleSubmit, formState: { errors }, formState, setValue } = useForm<ArticleSchema>(formOptions);
|
||||
|
||||
const save = async (data: any) => {
|
||||
const selectedLevel = Number(Array.from(levelValue).pop());
|
||||
const request = {
|
||||
name: data.name,
|
||||
aliasName: data.aliasName,
|
||||
levelNumber: selectedLevel,
|
||||
isActive: active,
|
||||
};
|
||||
|
||||
console.log(request);
|
||||
loading();
|
||||
const res = await createUserLevels(request);
|
||||
if (res.error) {
|
||||
error(res.message);
|
||||
return false;
|
||||
}
|
||||
close();
|
||||
successSubmit("/admin/master/master-user-level")
|
||||
}
|
||||
|
||||
async function onSubmit(data: any) {
|
||||
MySwal.fire({
|
||||
title: "Save Data",
|
||||
text: "",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
cancelButtonColor: "#d33",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "Save",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
save(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function successSubmit(redirect: string) {
|
||||
MySwal.fire({
|
||||
title: 'Sukses',
|
||||
icon: 'success',
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'OK',
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
router.push(redirect);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx-3 my-5">
|
||||
<div className="flex flex-col gap-3 mb-4">
|
||||
<Card className="w-full bg-white">
|
||||
<div className="w-full mr-2 p-5 ">
|
||||
<form method="POST" onSubmit={handleSubmit(onSubmit)}>
|
||||
<>
|
||||
<div className="flex flex-row gap-1">
|
||||
<div className="w-6/12 justify-start items-start mt-2 gap-3">
|
||||
<div className="flex flex-col ">
|
||||
<Input
|
||||
type="text"
|
||||
label="Nama"
|
||||
id="name"
|
||||
{...register("name")}
|
||||
placeholder="Input Name"
|
||||
labelPlacement="outside"
|
||||
className=" font-semibold"
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
input: "!text-black hover:!text-white focus:!text-white",
|
||||
inputWrapper: "max-h-[40px] bg-transparant border text-white",
|
||||
}}
|
||||
startContent={
|
||||
<div className="pointer-events-none flex items-center">
|
||||
<span className="text-default-400 text-small"></span>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
{errors.name?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.name?.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col mt-3">
|
||||
<Input
|
||||
type="text"
|
||||
label="Alias Name"
|
||||
id="aliasName"
|
||||
{...register("aliasName")}
|
||||
placeholder="Input Name"
|
||||
labelPlacement="outside"
|
||||
className=" font-semibold"
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
input: "!text-black hover:!text-white focus:!text-white",
|
||||
inputWrapper: "max-h-[40px] bg-transparant border text-white",
|
||||
}}
|
||||
startContent={
|
||||
<div className="pointer-events-none flex items-center">
|
||||
<span className="text-default-400 text-small"></span>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
{errors.aliasName?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.aliasName?.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-3 ">
|
||||
<p className="text-black text-sm mb-1 font-semibold">Level Number</p>
|
||||
<Select
|
||||
variant="bordered"
|
||||
labelPlacement="outside"
|
||||
placeholder="Select Polda"
|
||||
selectedKeys={levelValue}
|
||||
onSelectionChange={setLevelValue}
|
||||
className="w-full"
|
||||
classNames={{
|
||||
mainWrapper: "rounded",
|
||||
listboxWrapper:
|
||||
"bg-white w-full !text-indigo-500 text-center font-bold",
|
||||
popoverContent: "bg-white !text-indigo-500",
|
||||
trigger:
|
||||
"border-1 border-gray-200 hover:!bg-gray-100 !text-black",
|
||||
}}
|
||||
listboxProps={{
|
||||
itemClasses: {
|
||||
base: [
|
||||
"!text-left",
|
||||
"!bg-white",
|
||||
"text-indigo-500 ",
|
||||
"data-[selectable=true]:!text-indigo-500",
|
||||
"data-[pressed=true]:text-indigo-500",
|
||||
"data-[hover=true]:!text-indigo-300",
|
||||
],
|
||||
wrapper: ["!bg-white border-none"],
|
||||
},
|
||||
}}
|
||||
>
|
||||
<SelectSection showDivider title="List Level">
|
||||
{LevelList.map((list: any) => (
|
||||
<SelectItem key={list.id} value={list.id}>
|
||||
{list.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectSection>
|
||||
</Select>
|
||||
</div>
|
||||
{/* <div className="mt-3 ">
|
||||
<p className="text-black text-sm mb-1 font-semibold">Parent LevelId</p>
|
||||
<Select
|
||||
variant="bordered"
|
||||
selectionMode="single"
|
||||
labelPlacement="outside"
|
||||
placeholder="Select"
|
||||
className="font-semibold"
|
||||
items={moduleList}
|
||||
classNames={{
|
||||
mainWrapper: "rounded",
|
||||
listboxWrapper:
|
||||
"bg-white w-full !text-indigo-500 text-center font-bold",
|
||||
popoverContent: "bg-white !text-indigo-500",
|
||||
trigger:
|
||||
"border-1 border-gray-200 hover:!bg-gray-100 !text-black",
|
||||
}}
|
||||
listboxProps={{
|
||||
itemClasses: {
|
||||
base: [
|
||||
"!text-left",
|
||||
"!bg-white",
|
||||
"text-indigo-500 ",
|
||||
"data-[selectable=true]:!text-indigo-500",
|
||||
"data-[pressed=true]:text-indigo-500",
|
||||
"data-[hover=true]:!text-indigo-300",
|
||||
],
|
||||
wrapper: ["!bg-white border-none"],
|
||||
},
|
||||
}}
|
||||
renderValue={(items) => {
|
||||
return items.map((item) => (
|
||||
<span key={item.props?.value} className="text-black text-xs">
|
||||
{item.textValue}
|
||||
</span>
|
||||
));
|
||||
}}
|
||||
>
|
||||
<SelectSection showDivider title="Module">
|
||||
{moduleList.map((list) => (
|
||||
<SelectItem key={list.id} value={list.id}>
|
||||
{list.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectSection>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="mt-3 ">
|
||||
<p className="text-black text-sm mb-1 font-semibold">Provinsi</p>
|
||||
<Select
|
||||
variant="bordered"
|
||||
selectionMode="single"
|
||||
labelPlacement="outside"
|
||||
placeholder="Select"
|
||||
className="font-semibold"
|
||||
items={provinceList}
|
||||
classNames={{
|
||||
mainWrapper: "rounded",
|
||||
listboxWrapper:
|
||||
"bg-white w-full !text-indigo-500 text-center font-bold",
|
||||
popoverContent: "bg-white !text-indigo-500",
|
||||
trigger:
|
||||
"border-1 border-gray-200 hover:!bg-gray-100 !text-black",
|
||||
}}
|
||||
listboxProps={{
|
||||
itemClasses: {
|
||||
base: [
|
||||
"!text-left",
|
||||
"!bg-white",
|
||||
"text-indigo-500 ",
|
||||
"data-[selectable=true]:!text-indigo-500",
|
||||
"data-[pressed=true]:text-indigo-500",
|
||||
"data-[hover=true]:!text-indigo-300",
|
||||
],
|
||||
wrapper: ["!bg-white border-none"],
|
||||
},
|
||||
}}
|
||||
renderValue={(items) => {
|
||||
return items.map((item) => (
|
||||
<span key={item.props?.value} className="text-black text-xs">
|
||||
{item.textValue}
|
||||
</span>
|
||||
));
|
||||
}}
|
||||
>
|
||||
<SelectSection showDivider title="Provinsi">
|
||||
{provinceList.map((list) => (
|
||||
<SelectItem key={list.id} value={list.id}>
|
||||
{list.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectSection>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="text-black">
|
||||
<p className=" text-black ">Status</p>
|
||||
<RadioGroup
|
||||
orientation="horizontal"
|
||||
id="radio-banned"
|
||||
className="text-gray-950 mb-2"
|
||||
onChange={handleActive}
|
||||
defaultValue={active}
|
||||
>
|
||||
<Radio
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
}}
|
||||
value="true"
|
||||
>
|
||||
Active
|
||||
</Radio>
|
||||
<Radio
|
||||
classNames={{
|
||||
label: "!text-black",
|
||||
}}
|
||||
value="false"
|
||||
>
|
||||
Inactive
|
||||
</Radio>
|
||||
</RadioGroup>
|
||||
</div> */}
|
||||
<div className="flex flex-row gap-3 my-3">
|
||||
<Link href="/admin/master/master-user-level">
|
||||
<Button
|
||||
variant="bordered"
|
||||
className="bg-white border-grey-100 rounded-full text-[#8E5C18] mr-5"
|
||||
>
|
||||
Cancel
|
||||
</Button>{" "}
|
||||
</Link>
|
||||
<Button
|
||||
className="w-[50px]"
|
||||
color="primary"
|
||||
size="md"
|
||||
type="submit">
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-6/12 ">
|
||||
<div className="flex items-center justify-center justify-items-center h-full">
|
||||
<Image
|
||||
width={400}
|
||||
alt="NextUI hero Image"
|
||||
src="/account-category.jpg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</form>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div >
|
||||
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
"use client";
|
||||
import {
|
||||
TableCell,
|
||||
TableRow,
|
||||
Table,
|
||||
TableHeader,
|
||||
TableColumn,
|
||||
TableBody,
|
||||
Pagination,
|
||||
Dropdown,
|
||||
DropdownTrigger,
|
||||
DropdownMenu,
|
||||
DropdownItem,
|
||||
Input,
|
||||
User,
|
||||
Card,
|
||||
Divider,
|
||||
Chip,
|
||||
ChipProps,
|
||||
} from "@nextui-org/react";
|
||||
import { Button } from "@nextui-org/button";
|
||||
import React, { Key, useCallback, useMemo, useState } from "react";
|
||||
import {
|
||||
AddIcon,
|
||||
CreateIconIon,
|
||||
DeleteIcon,
|
||||
DotsYIcon,
|
||||
EyeFilledIcon,
|
||||
EyeIconMdi,
|
||||
} from "@/components/icons";
|
||||
import Link from "next/link";
|
||||
|
||||
type UserObject = {
|
||||
id: number;
|
||||
title: string;
|
||||
status: string;
|
||||
description: string;
|
||||
avatar: string;
|
||||
};
|
||||
|
||||
const statusColorMap = {
|
||||
active: "success",
|
||||
paused: "danger",
|
||||
vacation: "warning",
|
||||
};
|
||||
|
||||
|
||||
export default function MagazineTable() {
|
||||
type TableRow = (typeof magazineTable)[0];
|
||||
|
||||
const columns = [
|
||||
|
||||
{ name: "Title", uid: "title" },
|
||||
{ name: "Description", uid: "description" },
|
||||
{ name: "Action", uid: "actions" },
|
||||
];
|
||||
|
||||
const magazineTable = [
|
||||
{
|
||||
id: 1,
|
||||
title: "Proses pembuatan website humas ",
|
||||
status: "active",
|
||||
description: "Pembuatan website Humas adalah sebuah proses yang strategis untuk membangun identitas digital sebuah organisasi atau entitas, yang bertujuan untuk menyebarkan informasi kepada publik, memperkuat citra merek, serta menjaga keterbukaan dan transparansi. Proses ini melibatkan beberapa tahapan yang terstruktur dan terkoordinasi dengan baik",
|
||||
avatar: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSa8Luglga9J2R3Bxt_PsWZISUHQWODD6_ZTAJ5mIQgxYCAE-YbkY81faTqp-hSA_jVPTs&usqp=CAU",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "Proses pembuatan website humas ",
|
||||
status: "active",
|
||||
description: "Pembuatan website Humas adalah sebuah proses yang strategis untuk membangun identitas digital sebuah organisasi atau entitas, yang bertujuan untuk menyebarkan informasi kepada publik, memperkuat citra merek, serta menjaga keterbukaan dan transparansi. Proses ini melibatkan beberapa tahapan yang terstruktur dan terkoordinasi dengan baik",
|
||||
avatar: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSa8Luglga9J2R3Bxt_PsWZISUHQWODD6_ZTAJ5mIQgxYCAE-YbkY81faTqp-hSA_jVPTs&usqp=CAU",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "Proses pembuatan website humas ",
|
||||
status: "active",
|
||||
description: "Pembuatan website Humas adalah sebuah proses yang strategis untuk membangun identitas digital sebuah organisasi atau entitas, yang bertujuan untuk menyebarkan informasi kepada publik, memperkuat citra merek, serta menjaga keterbukaan dan transparansi. Proses ini melibatkan beberapa tahapan yang terstruktur dan terkoordinasi dengan baik",
|
||||
avatar: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSa8Luglga9J2R3Bxt_PsWZISUHQWODD6_ZTAJ5mIQgxYCAE-YbkY81faTqp-hSA_jVPTs&usqp=CAU",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "Proses pembuatan website humas ",
|
||||
status: "active",
|
||||
description: "Pembuatan website Humas adalah sebuah proses yang strategis untuk membangun identitas digital sebuah organisasi atau entitas, yang bertujuan untuk menyebarkan informasi kepada publik, memperkuat citra merek, serta menjaga keterbukaan dan transparansi. Proses ini melibatkan beberapa tahapan yang terstruktur dan terkoordinasi dengan baik",
|
||||
avatar: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSa8Luglga9J2R3Bxt_PsWZISUHQWODD6_ZTAJ5mIQgxYCAE-YbkY81faTqp-hSA_jVPTs&usqp=CAU",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: "Proses pembuatan website humas ",
|
||||
status: "active",
|
||||
description: "Pembuatan website Humas adalah sebuah proses yang strategis untuk membangun identitas digital sebuah organisasi atau entitas, yang bertujuan untuk menyebarkan informasi kepada publik, memperkuat citra merek, serta menjaga keterbukaan dan transparansi. Proses ini melibatkan beberapa tahapan yang terstruktur dan terkoordinasi dengan baik",
|
||||
avatar: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSa8Luglga9J2R3Bxt_PsWZISUHQWODD6_ZTAJ5mIQgxYCAE-YbkY81faTqp-hSA_jVPTs&usqp=CAU",
|
||||
},
|
||||
];
|
||||
|
||||
const renderCell = useCallback((magazine: TableRow, columnKey: Key) => {
|
||||
const cellValue = magazine[columnKey as keyof UserObject];
|
||||
const statusColorMap: Record<string, ChipProps["color"]> = {
|
||||
active: "primary",
|
||||
cancel: "danger",
|
||||
pending: "success",
|
||||
};
|
||||
|
||||
switch (columnKey) {
|
||||
case "no":
|
||||
return (
|
||||
<div>{magazine.id}</div>
|
||||
)
|
||||
|
||||
case "title":
|
||||
return (
|
||||
<div className="w-[350px]">{magazine.title}</div>
|
||||
)
|
||||
|
||||
case "description":
|
||||
return (
|
||||
<div className="">{magazine.description}</div>
|
||||
)
|
||||
|
||||
case "status":
|
||||
return (
|
||||
<Chip
|
||||
className="capitalize "
|
||||
color={statusColorMap[magazine.status]}
|
||||
size="lg"
|
||||
variant="flat"
|
||||
>
|
||||
<div className="flex flex-row items-center gap-2 justify-center">
|
||||
{cellValue}
|
||||
</div>
|
||||
</Chip>
|
||||
);
|
||||
|
||||
case "actions":
|
||||
return (
|
||||
<div className="relative flex justify-star items-center gap-2">
|
||||
<Dropdown className="lg:min-w-[150px] bg-black text-white shadow border ">
|
||||
<DropdownTrigger>
|
||||
<Button isIconOnly size="lg" variant="light">
|
||||
<DotsYIcon className="text-default-300" />
|
||||
</Button>
|
||||
</DropdownTrigger>
|
||||
<DropdownMenu>
|
||||
<DropdownItem
|
||||
>
|
||||
<Link
|
||||
href={`/admin/magazine/detail`}
|
||||
>
|
||||
<EyeIconMdi className="inline mr-2 mb-1" />
|
||||
Detail
|
||||
</Link>
|
||||
</DropdownItem>
|
||||
<DropdownItem
|
||||
>
|
||||
<Link
|
||||
href={`#`}
|
||||
>
|
||||
<CreateIconIon className="inline mr-2 mb-1" />
|
||||
Edit
|
||||
</Link>
|
||||
</DropdownItem>
|
||||
<DropdownItem
|
||||
>
|
||||
<Link
|
||||
href={`#`}
|
||||
>
|
||||
<DeleteIcon
|
||||
width={20}
|
||||
height={16}
|
||||
className="inline mr-2 mb-1"
|
||||
/>
|
||||
Delete
|
||||
</Link>
|
||||
</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
|
||||
default:
|
||||
return cellValue;
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mx-3 my-5">
|
||||
<Link href="/admin/magazine/create" >
|
||||
<Button className="my-3 bg-blue-600 text-white" ><CreateIconIon />Create New Magazine</Button>
|
||||
</Link>
|
||||
<div className="flex flex-col items-center rounded-2xl">
|
||||
<Table
|
||||
// selectionMode="multiple"
|
||||
aria-label="micro issue table"
|
||||
className="rounded-xl"
|
||||
classNames={{
|
||||
th: "bg-white dark:bg-black text-black dark:text-white border-b-1 text-md",
|
||||
base: "bg-white dark:bg-black border",
|
||||
wrapper: "min-h-[50px] bg-transpararent text-black dark:text-white ",
|
||||
}}
|
||||
>
|
||||
<TableHeader columns={columns}>
|
||||
{(column) => (
|
||||
<TableColumn key={column.uid}>{column.name}</TableColumn>
|
||||
)}
|
||||
</TableHeader>
|
||||
<TableBody items={magazineTable} emptyContent={"No data to display."}>
|
||||
{(item) => (
|
||||
<TableRow key={item.id}>
|
||||
{(columnKey) => (
|
||||
<TableCell>{renderCell(item, columnKey)}</TableCell>
|
||||
)}
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,231 @@
|
|||
"use client";
|
||||
import {
|
||||
TableCell,
|
||||
TableRow,
|
||||
Table,
|
||||
TableHeader,
|
||||
TableColumn,
|
||||
TableBody,
|
||||
Pagination,
|
||||
Dropdown,
|
||||
DropdownTrigger,
|
||||
DropdownMenu,
|
||||
DropdownItem,
|
||||
Input,
|
||||
User,
|
||||
Card,
|
||||
Divider,
|
||||
Chip,
|
||||
ChipProps,
|
||||
} from "@nextui-org/react";
|
||||
import { Button } from "@nextui-org/button";
|
||||
import React, { Key, useCallback, useMemo, useState } from "react";
|
||||
import {
|
||||
AddIcon,
|
||||
CreateIconIon,
|
||||
DeleteIcon,
|
||||
DotsYIcon,
|
||||
EyeFilledIcon,
|
||||
EyeIconMdi,
|
||||
} from "@/components/icons";
|
||||
import Link from "next/link";
|
||||
|
||||
type UserObject = {
|
||||
id: number;
|
||||
name: string;
|
||||
status: string;
|
||||
description: string;
|
||||
moduleName: string;
|
||||
pathUrl: string;
|
||||
};
|
||||
|
||||
const statusColorMap = {
|
||||
active: "success",
|
||||
paused: "danger",
|
||||
vacation: "warning",
|
||||
};
|
||||
|
||||
|
||||
export default function MenuDataTable() {
|
||||
type TableRow = (typeof menuDataTable)[0];
|
||||
|
||||
const columns = [
|
||||
{ name: "No", uid: "no" },
|
||||
{ name: "Name", uid: "name" },
|
||||
{ name: "Description", uid: "description" },
|
||||
{ name: "Module Name", uid: "moduleName" },
|
||||
{ name: "Path URL", uid: "pathUrl" },
|
||||
{ name: "Status", uid: "status" },
|
||||
{ name: "Action", uid: "actions" },
|
||||
];
|
||||
|
||||
const menuDataTable = [
|
||||
{
|
||||
id: 1,
|
||||
name: "AI Journalist ",
|
||||
status: "active",
|
||||
description: "AI Journalist",
|
||||
moduleName: "Multipool Acts",
|
||||
pathUrl: "/admin/acts",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "AI Journalist ",
|
||||
status: "active",
|
||||
description: "AI Journalist",
|
||||
moduleName: "Multipool Acts",
|
||||
pathUrl: "/admin/acts",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "AI Journalist ",
|
||||
status: "active",
|
||||
description: "AI Journalist",
|
||||
moduleName: "Multipool Acts",
|
||||
pathUrl: "/admin/acts",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "AI Journalist ",
|
||||
status: "active",
|
||||
description: "AI Journalist",
|
||||
moduleName: "Multipool Acts",
|
||||
pathUrl: "/admin/acts",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "AI Journalist ",
|
||||
status: "active",
|
||||
description: "AI Journalist",
|
||||
moduleName: "Multipool Acts",
|
||||
pathUrl: "/admin/acts",
|
||||
},
|
||||
];
|
||||
|
||||
const renderCell = useCallback((menuData: TableRow, columnKey: Key) => {
|
||||
const cellValue = menuData[columnKey as keyof UserObject];
|
||||
const statusColorMap: Record<string, ChipProps["color"]> = {
|
||||
active: "success",
|
||||
cancel: "danger",
|
||||
pending: "warning",
|
||||
};
|
||||
|
||||
switch (columnKey) {
|
||||
case "no":
|
||||
return (
|
||||
<div>{menuData.id}</div>
|
||||
)
|
||||
|
||||
case "name":
|
||||
return (
|
||||
<div className="w-[150px]">{menuData.name}</div>
|
||||
)
|
||||
|
||||
case "description":
|
||||
return (
|
||||
<div className="">{menuData.description}</div>
|
||||
)
|
||||
|
||||
case "status":
|
||||
return (
|
||||
<Chip
|
||||
className="capitalize "
|
||||
color={statusColorMap[menuData.status]}
|
||||
size="lg"
|
||||
variant="flat"
|
||||
>
|
||||
<div className="flex flex-row items-center gap-2 justify-center">
|
||||
{cellValue}
|
||||
</div>
|
||||
</Chip>
|
||||
);
|
||||
|
||||
case "actions":
|
||||
return (
|
||||
<div className="relative flex justify-star items-center gap-2">
|
||||
<Dropdown className="lg:min-w-[150px] bg-black text-white shadow border ">
|
||||
<DropdownTrigger>
|
||||
<Button isIconOnly size="lg" variant="light">
|
||||
<DotsYIcon className="text-default-300" />
|
||||
</Button>
|
||||
</DropdownTrigger>
|
||||
<DropdownMenu>
|
||||
<DropdownItem
|
||||
>
|
||||
<Link
|
||||
href={`/admin/magazine/detail`}
|
||||
>
|
||||
<EyeIconMdi className="inline mr-2 mb-1" />
|
||||
Detail
|
||||
</Link>
|
||||
</DropdownItem>
|
||||
<DropdownItem
|
||||
>
|
||||
<Link
|
||||
href={`#`}
|
||||
>
|
||||
<CreateIconIon className="inline mr-2 mb-1" />
|
||||
Edit
|
||||
</Link>
|
||||
</DropdownItem>
|
||||
<DropdownItem
|
||||
>
|
||||
<Link
|
||||
href={`#`}
|
||||
>
|
||||
<DeleteIcon
|
||||
width={20}
|
||||
height={16}
|
||||
className="inline mr-2 mb-1"
|
||||
/>
|
||||
Delete
|
||||
</Link>
|
||||
</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
|
||||
default:
|
||||
return cellValue;
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mx-3 my-5">
|
||||
<Link href="/admin/master/master-menu/menu-data/create" >
|
||||
<Button className="my-3 bg-blue-600 text-white" ><CreateIconIon />Add Master Menu</Button>
|
||||
</Link>
|
||||
<div className="flex flex-col items-center rounded-2xl">
|
||||
<Table
|
||||
// selectionMode="multiple"
|
||||
aria-label="micro issue table"
|
||||
className="rounded-xl"
|
||||
classNames={{
|
||||
th: "bg-white dark:bg-black text-black dark:text-white border-b-1 text-md",
|
||||
base: "bg-white dark:bg-black border",
|
||||
wrapper: "min-h-[50px] bg-transpararent text-black dark:text-white ",
|
||||
}}
|
||||
>
|
||||
<TableHeader columns={columns}>
|
||||
{(column) => (
|
||||
<TableColumn key={column.uid}>{column.name}</TableColumn>
|
||||
)}
|
||||
</TableHeader>
|
||||
<TableBody items={menuDataTable} emptyContent={"No data to display."}>
|
||||
{(item) => (
|
||||
<TableRow key={item.id}>
|
||||
{(columnKey) => (
|
||||
<TableCell>{renderCell(item, columnKey)}</TableCell>
|
||||
)}
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
"use client";
|
||||
import {
|
||||
TableCell,
|
||||
TableRow,
|
||||
Table,
|
||||
TableHeader,
|
||||
TableColumn,
|
||||
TableBody,
|
||||
Pagination,
|
||||
Dropdown,
|
||||
DropdownTrigger,
|
||||
DropdownMenu,
|
||||
DropdownItem,
|
||||
Input,
|
||||
User,
|
||||
Card,
|
||||
Divider,
|
||||
Chip,
|
||||
ChipProps,
|
||||
} from "@nextui-org/react";
|
||||
import { Button } from "@nextui-org/button";
|
||||
import React, { Key, useCallback, useMemo, useState } from "react";
|
||||
import {
|
||||
AddIcon,
|
||||
CreateIconIon,
|
||||
DeleteIcon,
|
||||
DotsYIcon,
|
||||
EyeFilledIcon,
|
||||
EyeIconMdi,
|
||||
} from "@/components/icons";
|
||||
import Link from "next/link";
|
||||
|
||||
type UserObject = {
|
||||
id: number;
|
||||
name: string;
|
||||
status: string;
|
||||
description: string;
|
||||
pathUrl: string;
|
||||
};
|
||||
|
||||
const statusColorMap = {
|
||||
active: "success",
|
||||
paused: "danger",
|
||||
vacation: "warning",
|
||||
};
|
||||
|
||||
|
||||
export default function MasterModuleTable() {
|
||||
type TableRow = (typeof masterModuleTable)[0];
|
||||
|
||||
const columns = [
|
||||
{ name: "No", uid: "no" },
|
||||
{ name: "Name", uid: "name" },
|
||||
{ name: "Description", uid: "description" },
|
||||
{ name: "Path URL", uid: "pathUrl" },
|
||||
{ name: "Status", uid: "status" },
|
||||
{ name: "Action", uid: "actions" },
|
||||
];
|
||||
|
||||
const masterModuleTable = [
|
||||
{
|
||||
id: 1,
|
||||
name: "AI Journalist ",
|
||||
status: "active",
|
||||
description: "AI Journalist",
|
||||
pathUrl: "/admin/acts",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "AI Journalist ",
|
||||
status: "active",
|
||||
description: "AI Journalist",
|
||||
pathUrl: "/admin/acts",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "AI Journalist ",
|
||||
status: "active",
|
||||
description: "AI Journalist",
|
||||
pathUrl: "/admin/acts",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "AI Journalist ",
|
||||
status: "active",
|
||||
description: "AI Journalist",
|
||||
pathUrl: "/admin/acts",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "AI Journalist ",
|
||||
status: "active",
|
||||
description: "AI Journalist",
|
||||
pathUrl: "/admin/acts",
|
||||
},
|
||||
];
|
||||
|
||||
const renderCell = useCallback((masterModule: TableRow, columnKey: Key) => {
|
||||
const cellValue = masterModule[columnKey as keyof UserObject];
|
||||
const statusColorMap: Record<string, ChipProps["color"]> = {
|
||||
active: "success",
|
||||
cancel: "danger",
|
||||
pending: "warning",
|
||||
};
|
||||
|
||||
switch (columnKey) {
|
||||
case "no":
|
||||
return (
|
||||
<div>{masterModule.id}</div>
|
||||
)
|
||||
|
||||
case "name":
|
||||
return (
|
||||
<div className="w-[150px]">{masterModule.name}</div>
|
||||
)
|
||||
|
||||
case "description":
|
||||
return (
|
||||
<div className="">{masterModule.description}</div>
|
||||
)
|
||||
|
||||
case "status":
|
||||
return (
|
||||
<Chip
|
||||
className="capitalize "
|
||||
color={statusColorMap[masterModule.status]}
|
||||
size="lg"
|
||||
variant="flat"
|
||||
>
|
||||
<div className="flex flex-row items-center gap-2 justify-center">
|
||||
{cellValue}
|
||||
</div>
|
||||
</Chip>
|
||||
);
|
||||
|
||||
case "actions":
|
||||
return (
|
||||
<div className="relative flex justify-star items-center gap-2">
|
||||
<Dropdown className="lg:min-w-[150px] bg-black text-white shadow border ">
|
||||
<DropdownTrigger>
|
||||
<Button isIconOnly size="lg" variant="light">
|
||||
<DotsYIcon className="text-default-300" />
|
||||
</Button>
|
||||
</DropdownTrigger>
|
||||
<DropdownMenu>
|
||||
<DropdownItem
|
||||
>
|
||||
<Link
|
||||
href={`/admin/magazine/detail`}
|
||||
>
|
||||
<EyeIconMdi className="inline mr-2 mb-1" />
|
||||
Detail
|
||||
</Link>
|
||||
</DropdownItem>
|
||||
<DropdownItem
|
||||
>
|
||||
<Link
|
||||
href={`#`}
|
||||
>
|
||||
<CreateIconIon className="inline mr-2 mb-1" />
|
||||
Edit
|
||||
</Link>
|
||||
</DropdownItem>
|
||||
<DropdownItem
|
||||
>
|
||||
<Link
|
||||
href={`#`}
|
||||
>
|
||||
<DeleteIcon
|
||||
width={20}
|
||||
height={16}
|
||||
className="inline mr-2 mb-1"
|
||||
/>
|
||||
Delete
|
||||
</Link>
|
||||
</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
|
||||
default:
|
||||
return cellValue;
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mx-3 my-5">
|
||||
<Link href="/admin/master/master-module/create" >
|
||||
<Button className="my-3 bg-blue-600 text-white" ><CreateIconIon />Add Master Module</Button>
|
||||
</Link>
|
||||
<div className="flex flex-col items-center rounded-2xl">
|
||||
<Table
|
||||
// selectionMode="multiple"
|
||||
aria-label="micro issue table"
|
||||
className="rounded-xl"
|
||||
classNames={{
|
||||
th: "bg-white dark:bg-black text-black dark:text-white border-b-1 text-md",
|
||||
base: "bg-white dark:bg-black border",
|
||||
wrapper: "min-h-[50px] bg-transpararent text-black dark:text-white ",
|
||||
}}
|
||||
>
|
||||
<TableHeader columns={columns}>
|
||||
{(column) => (
|
||||
<TableColumn key={column.uid}>{column.name}</TableColumn>
|
||||
)}
|
||||
</TableHeader>
|
||||
<TableBody items={masterModuleTable} emptyContent={"No data to display."}>
|
||||
{(item) => (
|
||||
<TableRow key={item.id}>
|
||||
{(columnKey) => (
|
||||
<TableCell>{renderCell(item, columnKey)}</TableCell>
|
||||
)}
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,241 @@
|
|||
"use client";
|
||||
import {
|
||||
TableCell,
|
||||
TableRow,
|
||||
Table,
|
||||
TableHeader,
|
||||
TableColumn,
|
||||
TableBody,
|
||||
Pagination,
|
||||
Dropdown,
|
||||
DropdownTrigger,
|
||||
DropdownMenu,
|
||||
DropdownItem,
|
||||
Input,
|
||||
User,
|
||||
Card,
|
||||
Divider,
|
||||
Chip,
|
||||
ChipProps,
|
||||
} from "@nextui-org/react";
|
||||
import { Button } from "@nextui-org/button";
|
||||
import React, { Key, useCallback, useEffect, useMemo, useState } from "react";
|
||||
import {
|
||||
AddIcon,
|
||||
CreateIconIon,
|
||||
DeleteIcon,
|
||||
DotsYIcon,
|
||||
EyeFilledIcon,
|
||||
EyeIconMdi,
|
||||
} from "@/components/icons";
|
||||
import Link from "next/link";
|
||||
import { getAllUserLevels } from "@/services/user-levels/user-levels-service";
|
||||
|
||||
type UserObject = {
|
||||
id: number;
|
||||
name: string;
|
||||
levelNumber: string;
|
||||
aliasName: string;
|
||||
parentLevelId: string;
|
||||
provinceId: string;
|
||||
status: string;
|
||||
};
|
||||
|
||||
const statusColorMap = {
|
||||
active: "success",
|
||||
paused: "danger",
|
||||
vacation: "warning",
|
||||
};
|
||||
|
||||
|
||||
export default function MasterUserLevelTable() {
|
||||
const [totalPage, setTotalPage] = useState(1);
|
||||
const [masterUserLevelTable, setmasterUserLevel] = useState<UserObject[]>([]);
|
||||
|
||||
type TableRow = (typeof masterUserLevelTable)[0];
|
||||
|
||||
const columns = [
|
||||
{ name: "No", uid: "no" },
|
||||
{ name: "Name", uid: "name" },
|
||||
{ name: "User Name", uid: "alias_name" },
|
||||
{ name: "Level Number", uid: "level_number" },
|
||||
{ name: "Parent Level", uid: "parent_level_id" },
|
||||
{ name: "Province", uid: "province_id" },
|
||||
{ name: "Status", uid: "is_active" },
|
||||
{ name: "Action", uid: "actions" },
|
||||
];
|
||||
|
||||
const [page, setPage] = useState(1);
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
async function fetchData() {
|
||||
const request = {
|
||||
page: page,
|
||||
limit: 10,
|
||||
|
||||
};
|
||||
const res = await getAllUserLevels(request);
|
||||
const data = res?.data?.data;
|
||||
setTotalPage(Math.ceil(res?.data?.total / 10));
|
||||
initUserData(10, data);
|
||||
}
|
||||
|
||||
function initUserData(limit: number, data?: any) {
|
||||
if (data) {
|
||||
console.log(data);
|
||||
const startIndex = limit * (page - 1);
|
||||
let iterate = 0;
|
||||
const newData = data.map((value: any) => {
|
||||
iterate++;
|
||||
value.no = startIndex + iterate;
|
||||
return value;
|
||||
});
|
||||
console.log("Data ::", newData);
|
||||
setmasterUserLevel(newData);
|
||||
}
|
||||
}
|
||||
|
||||
const renderCell = useCallback((masterUserLevel: TableRow, columnKey: Key) => {
|
||||
const cellValue = masterUserLevel[columnKey as keyof UserObject];
|
||||
const statusColorMap: Record<string, ChipProps["color"]> = {
|
||||
active: "success",
|
||||
cancel: "danger",
|
||||
pending: "warning",
|
||||
};
|
||||
|
||||
switch (columnKey) {
|
||||
case "no":
|
||||
return (
|
||||
<div>{masterUserLevel.id}</div>
|
||||
)
|
||||
|
||||
case "name":
|
||||
return (
|
||||
<div className="w-[150px]">{masterUserLevel.name}</div>
|
||||
)
|
||||
|
||||
case "alias_Name":
|
||||
return (
|
||||
<div className="">{masterUserLevel.aliasName}</div>
|
||||
)
|
||||
case "is_active":
|
||||
return (
|
||||
<Chip
|
||||
className="capitalize "
|
||||
color={statusColorMap[masterUserLevel.status]}
|
||||
size="lg"
|
||||
variant="flat"
|
||||
>
|
||||
<div className="flex flex-row items-center gap-2 justify-center">
|
||||
{cellValue}
|
||||
</div>
|
||||
</Chip>
|
||||
);
|
||||
|
||||
case "actions":
|
||||
return (
|
||||
<div className="relative flex justify-star items-center gap-2">
|
||||
<Dropdown className="lg:min-w-[150px] bg-black text-white shadow border ">
|
||||
<DropdownTrigger>
|
||||
<Button isIconOnly size="lg" variant="light">
|
||||
<DotsYIcon className="text-default-300" />
|
||||
</Button>
|
||||
</DropdownTrigger>
|
||||
<DropdownMenu>
|
||||
<DropdownItem
|
||||
>
|
||||
<Link
|
||||
href={`/admin/magazine/detail`}
|
||||
>
|
||||
<EyeIconMdi className="inline mr-2 mb-1" />
|
||||
Detail
|
||||
</Link>
|
||||
</DropdownItem>
|
||||
<DropdownItem
|
||||
>
|
||||
<Link
|
||||
href={`#`}
|
||||
>
|
||||
<CreateIconIon className="inline mr-2 mb-1" />
|
||||
Edit
|
||||
</Link>
|
||||
</DropdownItem>
|
||||
<DropdownItem
|
||||
>
|
||||
<Link
|
||||
href={`#`}
|
||||
>
|
||||
<DeleteIcon
|
||||
width={20}
|
||||
height={16}
|
||||
className="inline mr-2 mb-1"
|
||||
/>
|
||||
Delete
|
||||
</Link>
|
||||
</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
|
||||
default:
|
||||
return cellValue;
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mx-3 my-5">
|
||||
<Link href="/admin/master/master-user-level/create" >
|
||||
<Button className="my-3 bg-blue-600 text-white" ><CreateIconIon />Create New User Level</Button>
|
||||
</Link>
|
||||
<div className="flex flex-col items-center rounded-2xl">
|
||||
<Table
|
||||
// selectionMode="multiple"
|
||||
aria-label="micro issue table"
|
||||
className="rounded-xl"
|
||||
classNames={{
|
||||
th: "bg-white dark:bg-black text-black dark:text-white border-b-1 text-md",
|
||||
base: "bg-white dark:bg-black border",
|
||||
wrapper: "min-h-[50px] bg-transpararent text-black dark:text-white ",
|
||||
}}
|
||||
>
|
||||
<TableHeader columns={columns}>
|
||||
{(column) => (
|
||||
<TableColumn key={column.uid}>{column.name}</TableColumn>
|
||||
)}
|
||||
</TableHeader>
|
||||
<TableBody items={masterUserLevelTable} emptyContent={"No data to display."}>
|
||||
{(item) => (
|
||||
<TableRow key={item.id}>
|
||||
{(columnKey) => (
|
||||
<TableCell>{renderCell(item, columnKey)}</TableCell>
|
||||
)}
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<div className="mt-2">
|
||||
<Pagination
|
||||
isCompact
|
||||
showControls
|
||||
showShadow
|
||||
color="primary"
|
||||
classNames={{
|
||||
base: "bg-transparent",
|
||||
wrapper: "bg-transparent",
|
||||
}}
|
||||
page={page}
|
||||
total={totalPage}
|
||||
onChange={(page) => setPage(page)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -5,7 +5,7 @@
|
|||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"start": "next start -p 4000",
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
@ -24,6 +24,7 @@
|
|||
"@nextui-org/theme": "2.1.17",
|
||||
"@react-aria/ssr": "^3.8.0",
|
||||
"@react-aria/visually-hidden": "^3.8.6",
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/node": "20.5.7",
|
||||
"@types/react": "18.2.21",
|
||||
"@types/react-datepicker": "^6.0.1",
|
||||
|
|
@ -35,6 +36,7 @@
|
|||
"eslint": "8.48.0",
|
||||
"eslint-config-next": "14.0.2",
|
||||
"framer-motion": "^10.18.0",
|
||||
"html-react-parser": "^5.1.10",
|
||||
"intl-messageformat": "^10.5.0",
|
||||
"jodit-react": "^4.0.25",
|
||||
"next": "14.0.2",
|
||||
|
|
@ -55,6 +57,6 @@
|
|||
"tailwind-variants": "^0.1.18",
|
||||
"tailwindcss": "3.3.5",
|
||||
"typescript": "5.0.4",
|
||||
"zod": "^3.22.4"
|
||||
"zod": "^1.11.17"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
|
|
@ -0,0 +1,12 @@
|
|||
import axios from "axios";
|
||||
|
||||
const baseURL = "http://103.82.242.92:8888";
|
||||
|
||||
const axiosBaseInstance = axios.create({
|
||||
baseURL,
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
export default axiosBaseInstance;
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
import axios from "axios";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
const baseURL = "http://103.82.242.92:8800";
|
||||
|
||||
const refreshToken = Cookies.get("refresh_token");
|
||||
|
||||
const axiosInterceptorInstance = axios.create({
|
||||
baseURL,
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
// Request interceptor
|
||||
axiosInterceptorInstance.interceptors.request.use(
|
||||
(config) => {
|
||||
const accessToken = Cookies.get("access_token");
|
||||
if (accessToken) {
|
||||
if (config.headers)
|
||||
config.headers.Authorization = "Bearer " + accessToken;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
},
|
||||
);
|
||||
|
||||
// Response interceptor
|
||||
|
||||
|
||||
export default axiosInterceptorInstance;
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
import axiosBaseInstance from "./axios-base-instance";
|
||||
|
||||
export async function httpGet(pathUrl: any, headers: any) {
|
||||
const response = await axiosBaseInstance
|
||||
.get(pathUrl, { headers })
|
||||
.catch((error) => error.response);
|
||||
console.log("Response base svc : ", response);
|
||||
if (response?.data.success) {
|
||||
return {
|
||||
error: false,
|
||||
message: "success",
|
||||
data: response?.data,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
error: true,
|
||||
message: response?.data?.message || null,
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function httpPost(pathUrl: any, headers: any, data: any) {
|
||||
const response = await axiosBaseInstance
|
||||
.post(pathUrl, data, { headers })
|
||||
.catch(function (error) {
|
||||
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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
import axiosDisestagesInstance2 from "./axios-disestages-instance-2";
|
||||
|
||||
export async function httpPostDisestages(pathUrl: any, headers: any, data?: any) {
|
||||
const response = await axiosDisestagesInstance2
|
||||
.post(pathUrl, data, { headers })
|
||||
.catch(function (error) {
|
||||
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 httpGetDisestages(pathUrl: any, headers: any) {
|
||||
const response = await axiosDisestagesInstance2
|
||||
.get(pathUrl, { headers })
|
||||
.catch(function (error) {
|
||||
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 httpDelete(pathUrl: any) {
|
||||
// const response = await axiosDisestagesInstance
|
||||
// .delete(pathUrl, data, { headers })
|
||||
// .catch(function (error) {
|
||||
// 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,
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
import { useRouter } from "next/navigation";
|
||||
import axiosInterceptorInstance from "./axios-interceptor-instance";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
export async function httpGetInterceptor(pathUrl: any) {
|
||||
const response = await axiosInterceptorInstance
|
||||
.get(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 if (response?.status == 401) {
|
||||
Cookies.set("is_logout", "true");
|
||||
window.location.href = "/";
|
||||
return {
|
||||
error: true,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
error: true,
|
||||
message: response?.data?.message || response?.data || null,
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function httpPostInterceptor(pathUrl: any, data: any, headers?: any) {
|
||||
const response = await axiosInterceptorInstance
|
||||
.post(pathUrl, data, { headers })
|
||||
.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 if (response?.status == 401) {
|
||||
Cookies.set("is_logout", "true");
|
||||
window.location.href = "/";
|
||||
} else {
|
||||
return {
|
||||
error: true,
|
||||
message: response?.data?.message || response?.data || null,
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function httpDeleteInterceptor(pathUrl: any) {
|
||||
const response = await axiosInterceptorInstance
|
||||
.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 if (response?.status == 401) {
|
||||
Cookies.set("is_logout", "true");
|
||||
window.location.href = "/";
|
||||
} else {
|
||||
return {
|
||||
error: true,
|
||||
message: response?.data?.message || response?.data || null,
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import { httpGet, httpPost } from "../http-config/http-base-services";
|
||||
|
||||
|
||||
|
||||
export async function getAllUserLevels(data: any) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGet(`user-levels`, headers,);
|
||||
}
|
||||
|
||||
export async function getAccountById(id: string) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGet(`user-account/findById/${id}`, headers);
|
||||
|
||||
}
|
||||
|
||||
export async function createUserLevels(request: any) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpPost(`user-levels`, headers, request);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue