feat:content rewrite create article, fix landing
This commit is contained in:
parent
459ba05261
commit
eb1bd6903f
|
|
@ -21,7 +21,13 @@ import {
|
||||||
} from "@/service/article";
|
} from "@/service/article";
|
||||||
import ReactSelect from "react-select";
|
import ReactSelect from "react-select";
|
||||||
import makeAnimated from "react-select/animated";
|
import makeAnimated from "react-select/animated";
|
||||||
import { Checkbox, Chip } from "@nextui-org/react";
|
import {
|
||||||
|
Checkbox,
|
||||||
|
Chip,
|
||||||
|
Select,
|
||||||
|
SelectItem,
|
||||||
|
SelectSection,
|
||||||
|
} from "@nextui-org/react";
|
||||||
import GenerateSingleArticleForm from "./generate-ai-single-form";
|
import GenerateSingleArticleForm from "./generate-ai-single-form";
|
||||||
import { htmlToString } from "@/utils/global";
|
import { htmlToString } from "@/utils/global";
|
||||||
import { close, error, loading } from "@/config/swal";
|
import { close, error, loading } from "@/config/swal";
|
||||||
|
|
@ -32,6 +38,7 @@ import {
|
||||||
saveManualContext,
|
saveManualContext,
|
||||||
updateManualArticle,
|
updateManualArticle,
|
||||||
} from "@/service/generate-article";
|
} from "@/service/generate-article";
|
||||||
|
import GenerateContentRewriteForm from "./generate-ai-content-rewrite-form";
|
||||||
|
|
||||||
const CustomEditor = dynamic(
|
const CustomEditor = dynamic(
|
||||||
() => {
|
() => {
|
||||||
|
|
@ -99,6 +106,7 @@ export default function CreateArticleForm() {
|
||||||
);
|
);
|
||||||
const [thumbnailValidation, setThumbnailValidation] = useState("");
|
const [thumbnailValidation, setThumbnailValidation] = useState("");
|
||||||
const [diseData, setDiseData] = useState<DiseData>();
|
const [diseData, setDiseData] = useState<DiseData>();
|
||||||
|
const [selectedWritingType, setSelectedWritingType] = useState("single");
|
||||||
|
|
||||||
const { getRootProps, getInputProps } = useDropzone({
|
const { getRootProps, getInputProps } = useDropzone({
|
||||||
onDrop: (acceptedFiles) => {
|
onDrop: (acceptedFiles) => {
|
||||||
|
|
@ -108,6 +116,9 @@ export default function CreateArticleForm() {
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
multiple: true,
|
multiple: true,
|
||||||
|
accept: {
|
||||||
|
"image/*": [],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const formOptions = {
|
const formOptions = {
|
||||||
|
|
@ -475,15 +486,55 @@ export default function CreateArticleForm() {
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|
||||||
{useAi && (
|
{useAi && (
|
||||||
<GenerateSingleArticleForm
|
<div className="flex flex-col gap-2">
|
||||||
content={(data) => {
|
<Select
|
||||||
setDiseData(data);
|
label="Writing Style"
|
||||||
setValue(
|
variant="bordered"
|
||||||
"description",
|
labelPlacement="outside"
|
||||||
data?.articleBody ? data?.articleBody : ""
|
placeholder=""
|
||||||
);
|
selectedKeys={[selectedWritingType]}
|
||||||
}}
|
onChange={(e) =>
|
||||||
/>
|
e.target.value !== ""
|
||||||
|
? setSelectedWritingType(e.target.value)
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
className="w-full"
|
||||||
|
classNames={{
|
||||||
|
label: "!text-black",
|
||||||
|
value: "!text-black",
|
||||||
|
trigger: [
|
||||||
|
"border-1 rounded-lg",
|
||||||
|
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
|
||||||
|
],
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SelectSection>
|
||||||
|
<SelectItem key="single">Single Article</SelectItem>
|
||||||
|
<SelectItem key="rewrite">Content Rewrite</SelectItem>
|
||||||
|
</SelectSection>
|
||||||
|
</Select>
|
||||||
|
{selectedWritingType === "single" ? (
|
||||||
|
<GenerateSingleArticleForm
|
||||||
|
content={(data) => {
|
||||||
|
setDiseData(data);
|
||||||
|
setValue(
|
||||||
|
"description",
|
||||||
|
data?.articleBody ? data?.articleBody : ""
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<GenerateContentRewriteForm
|
||||||
|
content={(data) => {
|
||||||
|
setDiseData(data);
|
||||||
|
setValue(
|
||||||
|
"description",
|
||||||
|
data?.articleBody ? data?.articleBody : ""
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<p className="text-sm mt-3">Deskripsi</p>
|
<p className="text-sm mt-3">Deskripsi</p>
|
||||||
|
|
@ -575,6 +626,7 @@ export default function CreateArticleForm() {
|
||||||
type="file"
|
type="file"
|
||||||
multiple
|
multiple
|
||||||
className="w-fit h-fit"
|
className="w-fit h-fit"
|
||||||
|
accept="image/*"
|
||||||
onChange={handleFileChange}
|
onChange={handleFileChange}
|
||||||
/>
|
/>
|
||||||
{thumbnailValidation !== "" && (
|
{thumbnailValidation !== "" && (
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,9 @@ export default function EditArticleForm(props: { isDetail: boolean }) {
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
multiple: true,
|
multiple: true,
|
||||||
|
accept: {
|
||||||
|
"image/*": [],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const formOptions = {
|
const formOptions = {
|
||||||
|
|
@ -640,6 +643,7 @@ export default function EditArticleForm(props: { isDetail: boolean }) {
|
||||||
type="file"
|
type="file"
|
||||||
multiple
|
multiple
|
||||||
className="w-fit h-fit"
|
className="w-fit h-fit"
|
||||||
|
accept="image/*"
|
||||||
onChange={handleFileChange}
|
onChange={handleFileChange}
|
||||||
/>
|
/>
|
||||||
{thumbnailValidation !== "" && (
|
{thumbnailValidation !== "" && (
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,280 @@
|
||||||
|
"use client";
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Input,
|
||||||
|
Select,
|
||||||
|
SelectItem,
|
||||||
|
SelectSection,
|
||||||
|
} from "@nextui-org/react";
|
||||||
|
import { FormEvent, useEffect, useState } from "react";
|
||||||
|
import { Controller, useForm } from "react-hook-form";
|
||||||
|
import * as z from "zod";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { close, error, loading } from "@/config/swal";
|
||||||
|
import {
|
||||||
|
generateDataArticle,
|
||||||
|
getDetailArticle,
|
||||||
|
getGenerateKeywords,
|
||||||
|
getGenerateRewriter,
|
||||||
|
getGenerateTitle,
|
||||||
|
} from "@/service/generate-article";
|
||||||
|
import { delay } from "@/utils/global";
|
||||||
|
import dynamic from "next/dynamic";
|
||||||
|
|
||||||
|
const CustomEditor = dynamic(
|
||||||
|
() => {
|
||||||
|
return import("@/components/editor/custom-editor");
|
||||||
|
},
|
||||||
|
{ ssr: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
const writingStyle = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "Friendly",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "Professional",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: "Informational",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
name: "Neutral",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
name: "Witty",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const articleSize = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "News (300 - 900 words)",
|
||||||
|
value: "News",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "Info (900 - 2000 words)",
|
||||||
|
value: "Info",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: "Detail (2000 - 5000 words)",
|
||||||
|
value: "Detail",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
interface DiseData {
|
||||||
|
id: number;
|
||||||
|
articleBody: string;
|
||||||
|
title: string;
|
||||||
|
metaTitle: string;
|
||||||
|
description: string;
|
||||||
|
metaDescription: string;
|
||||||
|
mainKeyword: string;
|
||||||
|
additionalKeywords: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function GenerateContentRewriteForm(props: {
|
||||||
|
content: (data: DiseData) => void;
|
||||||
|
}) {
|
||||||
|
const [selectedWritingSyle, setSelectedWritingStyle] =
|
||||||
|
useState("Informational");
|
||||||
|
const [selectedArticleSize, setSelectedArticleSize] = useState("News");
|
||||||
|
const [selectedLanguage, setSelectedLanguage] = useState("id");
|
||||||
|
const [mainKeyword, setMainKeyword] = useState("");
|
||||||
|
const [articleIds, setArticleIds] = useState<number[]>([]);
|
||||||
|
const [selectedId, setSelectedId] = useState<number>();
|
||||||
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
|
|
||||||
|
const onSubmit = async () => {
|
||||||
|
loading();
|
||||||
|
const request = {
|
||||||
|
advConfig: "",
|
||||||
|
context: mainKeyword,
|
||||||
|
style: selectedWritingSyle,
|
||||||
|
sentiment: "Informational",
|
||||||
|
urlContext: null,
|
||||||
|
contextType: "article",
|
||||||
|
lang: selectedLanguage,
|
||||||
|
createdBy: "123123",
|
||||||
|
clientId: "humasClientIdtest",
|
||||||
|
};
|
||||||
|
const res = await getGenerateRewriter(request);
|
||||||
|
close();
|
||||||
|
if (res?.error) {
|
||||||
|
error("Error");
|
||||||
|
}
|
||||||
|
setArticleIds([...articleIds, res?.data?.data?.id]);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getArticleDetail();
|
||||||
|
}, [selectedId]);
|
||||||
|
|
||||||
|
const checkArticleStatus = async (data: string | null) => {
|
||||||
|
if (data === null) {
|
||||||
|
delay(7000).then(() => {
|
||||||
|
getArticleDetail();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getArticleDetail = async () => {
|
||||||
|
if (selectedId) {
|
||||||
|
const res = await getDetailArticle(selectedId);
|
||||||
|
const data = res?.data?.data;
|
||||||
|
checkArticleStatus(data?.articleBody);
|
||||||
|
if (data?.articleBody !== null) {
|
||||||
|
setIsLoading(false);
|
||||||
|
props.content(data);
|
||||||
|
} else {
|
||||||
|
setIsLoading(true);
|
||||||
|
props.content({
|
||||||
|
id: data?.id,
|
||||||
|
articleBody: "",
|
||||||
|
title: "",
|
||||||
|
metaTitle: "",
|
||||||
|
description: "",
|
||||||
|
metaDescription: "",
|
||||||
|
additionalKeywords: "",
|
||||||
|
mainKeyword: "",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<fieldset>
|
||||||
|
<form className="flex flex-col w-full mt-3">
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-5 w-full">
|
||||||
|
<Select
|
||||||
|
label="Writing Style"
|
||||||
|
variant="bordered"
|
||||||
|
labelPlacement="outside"
|
||||||
|
placeholder=""
|
||||||
|
selectedKeys={[selectedWritingSyle]}
|
||||||
|
onChange={(e) =>
|
||||||
|
e.target.value !== ""
|
||||||
|
? setSelectedWritingStyle(e.target.value)
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
className="w-full"
|
||||||
|
classNames={{
|
||||||
|
label: "!text-black",
|
||||||
|
value: "!text-black",
|
||||||
|
trigger: [
|
||||||
|
"border-1 rounded-lg",
|
||||||
|
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
|
||||||
|
],
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SelectSection>
|
||||||
|
{writingStyle.map((style) => (
|
||||||
|
<SelectItem key={style.name}>{style.name}</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectSection>
|
||||||
|
</Select>
|
||||||
|
<Select
|
||||||
|
label="Article Size"
|
||||||
|
variant="bordered"
|
||||||
|
labelPlacement="outside"
|
||||||
|
placeholder=""
|
||||||
|
selectedKeys={[selectedArticleSize]}
|
||||||
|
onChange={(e) =>
|
||||||
|
e.target.value !== ""
|
||||||
|
? setSelectedArticleSize(e.target.value)
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
className="w-full"
|
||||||
|
classNames={{
|
||||||
|
label: "!text-black",
|
||||||
|
value: "!text-black",
|
||||||
|
trigger: [
|
||||||
|
"border-1 rounded-lg",
|
||||||
|
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
|
||||||
|
],
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SelectSection>
|
||||||
|
{articleSize.map((size) => (
|
||||||
|
<SelectItem key={size.value}>{size.name}</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectSection>
|
||||||
|
</Select>
|
||||||
|
<Select
|
||||||
|
label="Bahasa"
|
||||||
|
variant="bordered"
|
||||||
|
labelPlacement="outside"
|
||||||
|
placeholder=""
|
||||||
|
selectedKeys={[selectedLanguage]}
|
||||||
|
onChange={(e) =>
|
||||||
|
e.target.value !== "" ? setSelectedLanguage(e.target.value) : ""
|
||||||
|
}
|
||||||
|
className="w-full"
|
||||||
|
classNames={{
|
||||||
|
label: "!text-black",
|
||||||
|
value: "!text-black",
|
||||||
|
trigger: [
|
||||||
|
"border-1 rounded-lg",
|
||||||
|
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
|
||||||
|
],
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SelectSection>
|
||||||
|
<SelectItem key="id">Indonesia</SelectItem>
|
||||||
|
<SelectItem key="en">English</SelectItem>
|
||||||
|
</SelectSection>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col mt-3">
|
||||||
|
<div className="flex flex-row gap-2 items-center">
|
||||||
|
<p className="text-sm">Text</p>
|
||||||
|
</div>
|
||||||
|
<div className="w-[78vw] lg:w-full">
|
||||||
|
<CustomEditor onChange={setMainKeyword} initialData={mainKeyword} />
|
||||||
|
</div>
|
||||||
|
{mainKeyword == "" && (
|
||||||
|
<p className="text-red-400 text-sm">Required</p>
|
||||||
|
)}
|
||||||
|
<Button
|
||||||
|
color="primary"
|
||||||
|
className="my-5 w-full py-5 text-xs md:text-base"
|
||||||
|
type="button"
|
||||||
|
onPress={onSubmit}
|
||||||
|
isDisabled={mainKeyword == ""}
|
||||||
|
>
|
||||||
|
Generate
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
{articleIds.length > 0 && (
|
||||||
|
<div className="flex flex-row gap-1">
|
||||||
|
{articleIds?.map((id) => (
|
||||||
|
<Button
|
||||||
|
onPress={() => setSelectedId(id)}
|
||||||
|
key={id}
|
||||||
|
isLoading={isLoading && selectedId == id}
|
||||||
|
color={
|
||||||
|
selectedId == id && isLoading
|
||||||
|
? "warning"
|
||||||
|
: selectedId == id
|
||||||
|
? "success"
|
||||||
|
: "default"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<p className={selectedId == id ? "text-white" : "text-black"}>
|
||||||
|
{id}
|
||||||
|
</p>
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</form>
|
||||||
|
</fieldset>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -388,7 +388,7 @@ export default function GenerateSingleArticleForm(props: {
|
||||||
</div>
|
</div>
|
||||||
{articleIds.length > 0 && (
|
{articleIds.length > 0 && (
|
||||||
<div className="flex flex-row gap-1">
|
<div className="flex flex-row gap-1">
|
||||||
{articleIds?.map((id) => (
|
{articleIds?.map((id, index) => (
|
||||||
<Button
|
<Button
|
||||||
onPress={() => setSelectedId(id)}
|
onPress={() => setSelectedId(id)}
|
||||||
key={id}
|
key={id}
|
||||||
|
|
@ -402,7 +402,7 @@ export default function GenerateSingleArticleForm(props: {
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<p className={selectedId == id ? "text-white" : "text-black"}>
|
<p className={selectedId == id ? "text-white" : "text-black"}>
|
||||||
{id}
|
Article {index}
|
||||||
</p>
|
</p>
|
||||||
</Button>
|
</Button>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ export default function BodyLayout() {
|
||||||
<div className="lg:w-[75%] space-y-7">
|
<div className="lg:w-[75%] space-y-7">
|
||||||
<CategorySatker />
|
<CategorySatker />
|
||||||
<RegionalNews />
|
<RegionalNews />
|
||||||
{/* <MedolUpdate /> */}
|
<MedolUpdate />
|
||||||
<MediaSocial />
|
<MediaSocial />
|
||||||
<ENewsPolri />
|
<ENewsPolri />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,12 @@ export default function CategorySatker() {
|
||||||
title: "Itwasum",
|
title: "Itwasum",
|
||||||
path: "/news/itwasum",
|
path: "/news/itwasum",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
img: "/assets/satker2/stik-ptik.svg",
|
||||||
|
title: "STIK-PTIK",
|
||||||
|
path: "/news/stik-ptik",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const SatkerAll = [
|
const SatkerAll = [
|
||||||
|
|
@ -305,14 +311,14 @@ export default function CategorySatker() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="text-center bg-[#DD8306] rounded-none md:rounded-lg h-auto lg:h-[338px] space-y-0 py-4 md:space-y-7 flex flex-col justify-center">
|
<div className="text-center bg-[#DD8306] rounded-none md:rounded-lg h-auto lg:h-[338px] space-y-0 py-4 md:space-y-7 flex flex-col justify-center">
|
||||||
<div className="text-white font-bold text-2xl underline underline-offset-4 decoration-red-600">
|
<div className="text-xl text-white w-full justify-center flex">
|
||||||
{t("kategoriSatker")}
|
<p className="border-b-3 border-[#C3170F] py-2 w-fit">
|
||||||
|
{" "}
|
||||||
|
{t("kategoriSatker")}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-around">
|
<div className="flex items-center justify-around">
|
||||||
<div>
|
<div className="gap-2 md:gap-4 lg:gap-6 grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6">
|
||||||
<ChevronLeftWhite />
|
|
||||||
</div>
|
|
||||||
<div className="gap-2 md:gap-4 lg:gap-6 grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5">
|
|
||||||
{list.map((item: any, index: any) => (
|
{list.map((item: any, index: any) => (
|
||||||
<Link
|
<Link
|
||||||
href={`/news/all?satker=${changeNameToSlug(item.title)}`}
|
href={`/news/all?satker=${changeNameToSlug(item.title)}`}
|
||||||
|
|
@ -328,9 +334,6 @@ export default function CategorySatker() {
|
||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<ChevronRightWhite />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -355,8 +358,12 @@ export default function CategorySatker() {
|
||||||
<ModalContent>
|
<ModalContent>
|
||||||
{(onClose) => (
|
{(onClose) => (
|
||||||
<>
|
<>
|
||||||
<ModalHeader className="flex flex-col text-[#DD8306] items-center min-h text-3xl font-semibold">
|
<ModalHeader className="flex flex-col text-black items-center min-h text-3xl font-semibold">
|
||||||
{t("kategoriSatker")}
|
<div className="text-xl text-black w-full justify-center flex">
|
||||||
|
<p className="border-b-3 border-[#C3170F] py-2 w-fit">
|
||||||
|
{t("kategoriSatker")}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</ModalHeader>
|
</ModalHeader>
|
||||||
<ModalBody className="flex flex-row flex-wrap justify-center text-center">
|
<ModalBody className="flex flex-row flex-wrap justify-center text-center">
|
||||||
{SatkerAll.map((item: any, index: any) => (
|
{SatkerAll.map((item: any, index: any) => (
|
||||||
|
|
@ -376,7 +383,7 @@ export default function CategorySatker() {
|
||||||
src={item.img}
|
src={item.img}
|
||||||
/>
|
/>
|
||||||
</Link>
|
</Link>
|
||||||
<p className="text-xs font-bold text-[#DD8306] pt-2">
|
<p className="text-xs font-bold text-black pt-2">
|
||||||
{item.title}
|
{item.title}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -115,12 +115,16 @@ export default function HeaderNews() {
|
||||||
className="text-xs text-left m-2 p-2 dark:bg-[#1E1616] bg-white rounded-md flex flex-row gap-2"
|
className="text-xs text-left m-2 p-2 dark:bg-[#1E1616] bg-white rounded-md flex flex-row gap-2"
|
||||||
key={data.id}
|
key={data.id}
|
||||||
>
|
>
|
||||||
<img
|
<Image
|
||||||
|
height={480}
|
||||||
|
width={480}
|
||||||
alt="headernews"
|
alt="headernews"
|
||||||
src={
|
src={
|
||||||
data?.thumbnailUrl == "" ? "no-image.jpg" : data?.thumbnailUrl
|
data?.thumbnailUrl == ""
|
||||||
|
? "/no-image.jpg"
|
||||||
|
: data?.thumbnailUrl
|
||||||
}
|
}
|
||||||
className="object-cover w-[18%] rounded-md"
|
className="object-cover w-[60px] h-[60px] rounded-md"
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<Link
|
<Link
|
||||||
|
|
|
||||||
|
|
@ -91,9 +91,31 @@ export default function MedolUpdate() {
|
||||||
navigation={true}
|
navigation={true}
|
||||||
modules={[Navigation, Pagination]}
|
modules={[Navigation, Pagination]}
|
||||||
spaceBetween={40}
|
spaceBetween={40}
|
||||||
slidesPerView={2}
|
slidesPerView={1}
|
||||||
|
breakpoints={{
|
||||||
|
// When the window width is less than 640px
|
||||||
|
720: {
|
||||||
|
slidesPerView: 2, // Set slidesPerView to 1 on mobile
|
||||||
|
},
|
||||||
|
}}
|
||||||
pagination={true}
|
pagination={true}
|
||||||
className="mySwiper"
|
className="mySwiper"
|
||||||
|
onSwiper={(swiper) => {
|
||||||
|
swiper.navigation.nextEl?.classList.add(
|
||||||
|
"bg-white/70",
|
||||||
|
"!text-black",
|
||||||
|
"rounded-full",
|
||||||
|
"!w-[40px]",
|
||||||
|
"!h-[40px]"
|
||||||
|
);
|
||||||
|
swiper.navigation.prevEl?.classList.add(
|
||||||
|
"bg-white/70",
|
||||||
|
"!text-black",
|
||||||
|
"rounded-full",
|
||||||
|
"!w-[40px]",
|
||||||
|
"!h-[40px]"
|
||||||
|
);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{mediahubUpdate?.map((newsItem: any) => (
|
{mediahubUpdate?.map((newsItem: any) => (
|
||||||
<SwiperSlide key={newsItem.title}>
|
<SwiperSlide key={newsItem.title}>
|
||||||
|
|
@ -108,7 +130,7 @@ export default function MedolUpdate() {
|
||||||
radius="lg"
|
radius="lg"
|
||||||
width="300%"
|
width="300%"
|
||||||
alt="tes"
|
alt="tes"
|
||||||
className="object-cover h-[270px]"
|
className="object-cover !h-[30vh]"
|
||||||
src={newsItem.thumbnailLink}
|
src={newsItem.thumbnailLink}
|
||||||
/>
|
/>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
|
|
@ -141,9 +163,31 @@ export default function MedolUpdate() {
|
||||||
navigation={true}
|
navigation={true}
|
||||||
modules={[Navigation, Pagination]}
|
modules={[Navigation, Pagination]}
|
||||||
spaceBetween={40}
|
spaceBetween={40}
|
||||||
slidesPerView={2}
|
slidesPerView={1}
|
||||||
|
breakpoints={{
|
||||||
|
// When the window width is less than 640px
|
||||||
|
720: {
|
||||||
|
slidesPerView: 2, // Set slidesPerView to 1 on mobile
|
||||||
|
},
|
||||||
|
}}
|
||||||
pagination={true}
|
pagination={true}
|
||||||
className="mySwiper"
|
className="mySwiper"
|
||||||
|
onSwiper={(swiper) => {
|
||||||
|
swiper.navigation.nextEl?.classList.add(
|
||||||
|
"bg-white/70",
|
||||||
|
"!text-black",
|
||||||
|
"rounded-full",
|
||||||
|
"!w-[40px]",
|
||||||
|
"!h-[40px]"
|
||||||
|
);
|
||||||
|
swiper.navigation.prevEl?.classList.add(
|
||||||
|
"bg-white/70",
|
||||||
|
"!text-black",
|
||||||
|
"rounded-full",
|
||||||
|
"!w-[40px]",
|
||||||
|
"!h-[40px]"
|
||||||
|
);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{tbnUpdate?.map((newsItem: any) => (
|
{tbnUpdate?.map((newsItem: any) => (
|
||||||
<SwiperSlide key={newsItem.title}>
|
<SwiperSlide key={newsItem.title}>
|
||||||
|
|
@ -158,7 +202,7 @@ export default function MedolUpdate() {
|
||||||
radius="lg"
|
radius="lg"
|
||||||
width="300%"
|
width="300%"
|
||||||
alt="tes"
|
alt="tes"
|
||||||
className="object-cover h-[270px]"
|
className="object-cover !h-[30vh]"
|
||||||
src={newsItem?.image}
|
src={newsItem?.image}
|
||||||
/>
|
/>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
|
|
@ -189,9 +233,31 @@ export default function MedolUpdate() {
|
||||||
navigation={true}
|
navigation={true}
|
||||||
modules={[Navigation, Pagination]}
|
modules={[Navigation, Pagination]}
|
||||||
spaceBetween={40}
|
spaceBetween={40}
|
||||||
slidesPerView={2}
|
slidesPerView={1}
|
||||||
|
breakpoints={{
|
||||||
|
// When the window width is less than 640px
|
||||||
|
720: {
|
||||||
|
slidesPerView: 2, // Set slidesPerView to 1 on mobile
|
||||||
|
},
|
||||||
|
}}
|
||||||
pagination={true}
|
pagination={true}
|
||||||
className="mySwiper"
|
className="mySwiper"
|
||||||
|
onSwiper={(swiper) => {
|
||||||
|
swiper.navigation.nextEl?.classList.add(
|
||||||
|
"bg-white/70",
|
||||||
|
"!text-black",
|
||||||
|
"rounded-full",
|
||||||
|
"!w-[40px]",
|
||||||
|
"!h-[40px]"
|
||||||
|
);
|
||||||
|
swiper.navigation.prevEl?.classList.add(
|
||||||
|
"bg-white/70",
|
||||||
|
"!text-black",
|
||||||
|
"rounded-full",
|
||||||
|
"!w-[40px]",
|
||||||
|
"!h-[40px]"
|
||||||
|
);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{inpUpdate?.map((newsItem: any) => (
|
{inpUpdate?.map((newsItem: any) => (
|
||||||
<SwiperSlide key={newsItem?.id}>
|
<SwiperSlide key={newsItem?.id}>
|
||||||
|
|
@ -206,7 +272,7 @@ export default function MedolUpdate() {
|
||||||
radius="lg"
|
radius="lg"
|
||||||
width="300%"
|
width="300%"
|
||||||
alt="tes"
|
alt="tes"
|
||||||
className="object-cover h-[270px]"
|
className="object-cover !h-[30vh]"
|
||||||
src={newsItem.image}
|
src={newsItem.image}
|
||||||
/>
|
/>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
|
|
|
||||||
|
|
@ -135,9 +135,11 @@ export default function DetailNews(props: { data: any; listArticle: any }) {
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-center my-2 lg:my-5">
|
<div className="flex justify-center my-2 lg:my-5">
|
||||||
<img
|
<Image
|
||||||
alt="NextUI hero Image"
|
width={1440}
|
||||||
src={`http://38.47.180.165:8802${data?.files[imageNow]?.file_url}`}
|
height={1080}
|
||||||
|
alt="Main Image"
|
||||||
|
src={data?.files[imageNow]?.file_url}
|
||||||
className="object-cover w-[100%] rounded-md"
|
className="object-cover w-[100%] rounded-md"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -149,10 +151,12 @@ export default function DetailNews(props: { data: any; listArticle: any }) {
|
||||||
onClick={() => setImageNow(index)}
|
onClick={() => setImageNow(index)}
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
>
|
>
|
||||||
<img
|
<Image
|
||||||
|
width={480}
|
||||||
|
height={480}
|
||||||
alt="NextUI hero Image"
|
alt="NextUI hero Image"
|
||||||
src={`http://38.47.180.165:8802${file?.file_url}`}
|
src={file?.file_url}
|
||||||
className="object-cover h-[50px] lg:h-[100px] rounded-md"
|
className="object-cover w-[75px] lg:w-[150px] h-[50px] lg:h-[100px] rounded-md"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -273,16 +273,22 @@ export default function ArticleTable() {
|
||||||
label=""
|
label=""
|
||||||
variant="bordered"
|
variant="bordered"
|
||||||
labelPlacement="outside"
|
labelPlacement="outside"
|
||||||
placeholder="Select"
|
placeholder="Kategori"
|
||||||
selectionMode="multiple"
|
selectionMode="multiple"
|
||||||
selectedKeys={[selectedCategories]}
|
selectedKeys={selectedCategories}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
|
items={categories}
|
||||||
classNames={{ trigger: "border-1" }}
|
classNames={{ trigger: "border-1" }}
|
||||||
onChange={(e) => {
|
onSelectionChange={setSelectedCategories}
|
||||||
e.target.value === ""
|
renderValue={(items) => {
|
||||||
? ""
|
return items.map((item) => (
|
||||||
: setSelectedCategories(e.target.value);
|
<span
|
||||||
console.log("eeess", e.target.value);
|
key={item.props?.value}
|
||||||
|
className="text-black text-xs"
|
||||||
|
>
|
||||||
|
{item.textValue},
|
||||||
|
</span>
|
||||||
|
));
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{categories?.map((category: any) => (
|
{categories?.map((category: any) => (
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
eslint: {
|
eslint: {
|
||||||
ignoreDuringBuilds: true,
|
ignoreDuringBuilds: true,
|
||||||
},
|
},
|
||||||
images: {
|
images: {
|
||||||
domains: ['38.47.180.165'],
|
remotePatterns: [
|
||||||
},
|
{
|
||||||
}
|
hostname: "*",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = nextConfig
|
module.exports = nextConfig;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue