Merge branch 'dev-anang' of https://gitlab.com/hanifsalafi/mediahub_redesign
This commit is contained in:
commit
608afb32c2
|
|
@ -12,32 +12,22 @@ import { Calendar } from "@/components/ui/calendar";
|
|||
import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
||||
import { Plus } from "lucide-react";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { CalendarCategory } from "./data";
|
||||
import { EventContentArg } from "@fullcalendar/core";
|
||||
import EventModal from "./event-modal";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { getAgendaSettingsList } from "@/service/agenda-setting/agenda-setting";
|
||||
import dayjs from "dayjs";
|
||||
import { getCookiesDecrypt } from "@/lib/utils";
|
||||
import { CalendarCategory } from "./data";
|
||||
|
||||
const wait = () => new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
interface CalendarViewProps {
|
||||
events: CalendarEvent[];
|
||||
// events: CalendarEvent[];
|
||||
categories: CalendarCategory[];
|
||||
}
|
||||
|
||||
const INITIAL_YEAR = dayjs().format("YYYY");
|
||||
const INITIAL_MONTH = dayjs().format("M");
|
||||
export interface CalendarEvent {
|
||||
id: string;
|
||||
title: string;
|
||||
start: Date;
|
||||
end: Date;
|
||||
allDay: boolean;
|
||||
extendedProps: {
|
||||
calendar: string;
|
||||
description?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface AgendaSettingsAPIResponse {
|
||||
id: number;
|
||||
|
|
@ -59,14 +49,11 @@ interface APIResponse {
|
|||
data: AgendaSettingsAPIResponse[] | null; // `data` bisa berupa array atau null
|
||||
}
|
||||
|
||||
const CalendarView = ({ events, categories }: CalendarViewProps) => {
|
||||
const CalendarView = ({ categories }: CalendarViewProps) => {
|
||||
const [selectedCategory, setSelectedCategory] = useState<string[] | null>(
|
||||
null
|
||||
);
|
||||
const [selectedEventDate, setSelectedEventDate] = useState<Date | null>(null);
|
||||
// const [selectedEvent, setSelectedEvent] = useState<CalendarEvent | null>(
|
||||
// null
|
||||
// );
|
||||
const roleId = Number(getCookiesDecrypt("urie")) || 0;
|
||||
const [apiEvents, setApiEvents] = useState<CalendarEvent[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
|
|
@ -84,36 +71,47 @@ const CalendarView = ({ events, categories }: CalendarViewProps) => {
|
|||
{ title: "Create New theme", id: "104", tag: "etc" },
|
||||
]);
|
||||
|
||||
const [calendarEvents, setCalendarEvents] = useState<CalendarEvent[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
getCalendarEvents();
|
||||
});
|
||||
}, []);
|
||||
|
||||
const getCalendarEvents = async () => {
|
||||
const res = await getAgendaSettingsList(INITIAL_YEAR, INITIAL_MONTH, "");
|
||||
console.log("ress", res);
|
||||
console.log("API Response:", res);
|
||||
|
||||
if (res.error) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Map API data to the calendarEvents structure
|
||||
const events = res?.data?.data.map((event: any) => ({
|
||||
id: event.id.toString(),
|
||||
title: event.title,
|
||||
start: new Date(event.startDate),
|
||||
end: new Date(event.endDate),
|
||||
allDay: true, // Assuming all events are all-day by default
|
||||
extendedProps: {
|
||||
calendar: event.agendaType, // Map agendaType to the calendar category
|
||||
description: event.description,
|
||||
},
|
||||
}));
|
||||
|
||||
setCalendarEvents(events);
|
||||
console.log("event", events);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedCategory(categories?.map((c) => c.value));
|
||||
}, [events, categories]);
|
||||
}, [categories]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("Fetched events from API:", apiEvents);
|
||||
}, [apiEvents]);
|
||||
|
||||
const filteredEvents = apiEvents?.filter((event) =>
|
||||
const filteredEvents = calendarEvents?.filter((event) =>
|
||||
selectedCategory?.includes(event.extendedProps.calendar)
|
||||
);
|
||||
|
||||
const displayedEvents =
|
||||
filteredEvents?.length > 0 ? filteredEvents : apiEvents;
|
||||
|
||||
useEffect(() => {
|
||||
console.log("Filtered events based on category:", displayedEvents);
|
||||
}, [filteredEvents, apiEvents]);
|
||||
filteredEvents?.length > 1 ? filteredEvents : apiEvents;
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedCategory(categories?.map((c) => c.value));
|
||||
|
|
@ -151,6 +149,7 @@ const CalendarView = ({ events, categories }: CalendarViewProps) => {
|
|||
description: item.description,
|
||||
},
|
||||
}));
|
||||
|
||||
setApiEvents(eventsFromAPI);
|
||||
} else {
|
||||
console.warn("No events found in API response.");
|
||||
|
|
@ -167,6 +166,14 @@ const CalendarView = ({ events, categories }: CalendarViewProps) => {
|
|||
fetchAgendaEvents();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("Fetched events from API 1:", apiEvents);
|
||||
}, [apiEvents]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("Filtered events based on category 1:", calendarEvents);
|
||||
}, [filteredEvents, apiEvents]);
|
||||
|
||||
useEffect(() => {
|
||||
const draggableEl = document.getElementById("external-events");
|
||||
|
||||
|
|
@ -247,17 +254,16 @@ const CalendarView = ({ events, categories }: CalendarViewProps) => {
|
|||
<div className="grid grid-cols-12 gap-6 divide-x divide-border">
|
||||
<Card className="col-span-12 lg:col-span-4 2xl:col-span-3 pb-5">
|
||||
<CardContent className="p-0">
|
||||
{roleId === 11 && (
|
||||
<CardHeader className="border-none mb-2 pt-5">
|
||||
<Button
|
||||
onClick={handleDateClick}
|
||||
className="dark:bg-background dark:text-foreground"
|
||||
>
|
||||
<Plus className="w-4 h-4 me-1" />
|
||||
{"Tambahkan Agenda baru"}
|
||||
</Button>
|
||||
</CardHeader>
|
||||
)}
|
||||
<CardHeader className="border-none mb-2 pt-5">
|
||||
<Button
|
||||
onClick={handleDateClick}
|
||||
className="dark:bg-background dark:text-foreground"
|
||||
>
|
||||
<Plus className="w-4 h-4 me-1" />
|
||||
{"Tambahkan Agenda baru"}
|
||||
</Button>
|
||||
</CardHeader>
|
||||
|
||||
<div className="px-3">
|
||||
<Calendar
|
||||
mode="single"
|
||||
|
|
@ -321,7 +327,7 @@ const CalendarView = ({ events, categories }: CalendarViewProps) => {
|
|||
headerToolbar={{
|
||||
left: "prev,next today",
|
||||
center: "title",
|
||||
right: "dayGridMonth,timeGridWeek,timeGridDay,listWeek",
|
||||
right: "dayGridMonth,listWeek,",
|
||||
}}
|
||||
events={displayedEvents}
|
||||
editable={true}
|
||||
|
|
@ -352,3 +358,15 @@ const CalendarView = ({ events, categories }: CalendarViewProps) => {
|
|||
};
|
||||
|
||||
export default CalendarView;
|
||||
|
||||
export type CalendarEvent = {
|
||||
id: string;
|
||||
title: string;
|
||||
start: Date;
|
||||
end: Date;
|
||||
allDay: boolean;
|
||||
extendedProps: {
|
||||
calendar: string;
|
||||
description: string;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,15 +13,6 @@ const nextMonth = date.getMonth() === 11 ? new Date(date.getFullYear() + 1, 0, 1
|
|||
// prettier-ignore
|
||||
const prevMonth = date.getMonth() === 11 ? new Date(date.getFullYear() - 1, 0, 1) : new Date(date.getFullYear(), date.getMonth() - 1, 1)
|
||||
|
||||
export const getCalendarEvents = async () => {
|
||||
const res = await getAgendaSettingsList(INITIAL_YEAR, INITIAL_MONTH, "");
|
||||
if (res.error) {
|
||||
return false;
|
||||
}
|
||||
console.log("ress", res.data.data);
|
||||
return res?.data?.data;
|
||||
};
|
||||
|
||||
export const calendarEvents = [
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
|
|
@ -94,7 +85,7 @@ export const calendarEvents = [
|
|||
export const calendarCategories = [
|
||||
{
|
||||
label: "Nasional",
|
||||
value: "national",
|
||||
value: "mabes",
|
||||
activeClass: "ring-primary-500 bg-primary-500",
|
||||
className: "group-hover:border-blue-500",
|
||||
},
|
||||
|
|
@ -127,7 +118,7 @@ export const calendarCategories = [
|
|||
export const categories = [
|
||||
{
|
||||
label: "Nasional",
|
||||
value: "national",
|
||||
value: "mabes",
|
||||
className:
|
||||
"data-[state=checked]:bg-primary data-[state=checked]:ring-primary",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ const EventModal = ({
|
|||
|
||||
const reqData = {
|
||||
title: data.title,
|
||||
description: data.description || "",
|
||||
description: data.description,
|
||||
agendaType: calendarProps,
|
||||
startDate: format(startDate, "yyyy-MM-dd"),
|
||||
endDate: format(endDate, "yyyy-MM-dd"),
|
||||
|
|
@ -162,7 +162,7 @@ const EventModal = ({
|
|||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "OK",
|
||||
}).then(() => {
|
||||
router.push("/contributor/agenda-setting");
|
||||
router.push("en/contributor/agenda-setting");
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -272,11 +272,18 @@ const EventModal = ({
|
|||
<div className="space-y-4 pb-5 ">
|
||||
<div className="space-y-1.5">
|
||||
<Label htmlFor="title">Judul Agenda</Label>
|
||||
<Input
|
||||
id="title"
|
||||
type="text"
|
||||
placeholder="Enter Event Name"
|
||||
{...register("title")}
|
||||
<Controller
|
||||
control={control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors?.title?.message && (
|
||||
<div className="text-destructive text-sm">
|
||||
|
|
@ -475,10 +482,16 @@ const EventModal = ({
|
|||
)}
|
||||
<div className="space-y-1.5">
|
||||
<Label htmlFor="description">Isi Agenda Setting</Label>
|
||||
<Textarea
|
||||
id="description"
|
||||
placeholder="Enter Event Name"
|
||||
{...register("description")}
|
||||
<Controller
|
||||
control={control}
|
||||
name="description"
|
||||
render={({ field }) => (
|
||||
<Textarea
|
||||
defaultValue={field.value}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors?.description?.message && (
|
||||
<div className="text-destructive text-sm">
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { getEvents, getCategories } from "./utils";
|
||||
import { Category } from "./data";
|
||||
import { calendarEvents, Category } from "./data";
|
||||
import CalendarView from "./calender-view";
|
||||
|
||||
const CalenderPage = async () => {
|
||||
|
|
@ -11,7 +11,7 @@ const CalenderPage = async () => {
|
|||
}));
|
||||
return (
|
||||
<div>
|
||||
<CalendarView events={events} categories={formattedCategories} />
|
||||
<CalendarView categories={formattedCategories} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -63,12 +63,12 @@ const ReactTableImagePage = () => {
|
|||
Unggah Foto
|
||||
</Button>
|
||||
</Link>
|
||||
<Link href={"/contributor/content/image/createAi"}>
|
||||
{/* <Link href={"/contributor/content/image/createAi"}>
|
||||
<Button color="primary" className="text-white ml-3">
|
||||
<UploadIcon />
|
||||
Unggah Foto Dengan AI
|
||||
</Button>
|
||||
</Link>
|
||||
</Link> */}
|
||||
</div>
|
||||
</div>
|
||||
</CardTitle>
|
||||
|
|
|
|||
|
|
@ -31,6 +31,14 @@ import {
|
|||
uploadThumbnail,
|
||||
} from "@/service/content/content";
|
||||
import { uploadThumbnailBlog } from "@/service/blog/blog";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import {
|
||||
generateDataArticle,
|
||||
getDetailArticle,
|
||||
getGenerateKeywords,
|
||||
getGenerateTitle,
|
||||
} from "@/service/content/ai";
|
||||
import { getCookiesDecrypt } from "@/lib/utils";
|
||||
|
||||
const imageSchema = z.object({
|
||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
|
|
@ -56,12 +64,33 @@ export default function FormImage() {
|
|||
const taskId = Cookies.get("taskId");
|
||||
const scheduleId = Cookies.get("scheduleId");
|
||||
const scheduleType = Cookies.get("scheduleType");
|
||||
const roleId = getCookiesDecrypt("urie");
|
||||
|
||||
const [categories, setCategories] = useState<Category[]>([]);
|
||||
const [selectedCategory, setSelectedCategory] = useState<any>();
|
||||
const [tags, setTags] = useState<any[]>([]);
|
||||
const [thumbnail, setThumbnail] = useState<File | null>(null);
|
||||
const [preview, setPreview] = useState<string | null>(null);
|
||||
const [selectedLanguage, setSelectedLanguage] = useState("");
|
||||
|
||||
const [selectedSEO, setSelectedSEO] = useState<string>("");
|
||||
const [title, setTitle] = useState<string>("");
|
||||
const [selectedAdvConfig, setSelectedAdvConfig] = useState<string>("");
|
||||
const [editingArticleId, setEditingArticleId] = useState<string | null>(null);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
|
||||
const [articleIds, setArticleIds] = useState<string[]>([]);
|
||||
const [isGeneratedArticle, setIsGeneratedArticle] = useState(false);
|
||||
const [articleBody, setArticleBody] = useState<string>("");
|
||||
const [selectedArticleId, setSelectedArticleId] = useState<string | null>(
|
||||
null
|
||||
);
|
||||
const [selectedMainKeyword, setSelectedMainKeyword] = useState("");
|
||||
const [selectedWritingStyle, setSelectedWritingStyle] = useState("");
|
||||
const [selectedSize, setSelectedSize] = useState("");
|
||||
const [detailData, setDetailData] = useState<any>(null);
|
||||
const [articleImages, setArticleImages] = useState<string[]>([]);
|
||||
const [isSwitchOn, setIsSwitchOn] = useState<boolean>(false);
|
||||
|
||||
const [selectedTarget, setSelectedTarget] = useState("");
|
||||
const [unitSelection, setUnitSelection] = useState({
|
||||
|
|
@ -82,6 +111,161 @@ export default function FormImage() {
|
|||
resolver: zodResolver(imageSchema),
|
||||
});
|
||||
|
||||
const doGenerateMainKeyword = async () => {
|
||||
console.log(selectedMainKeyword);
|
||||
if (selectedMainKeyword?.length > 1) {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const titleData = {
|
||||
keyword: selectedMainKeyword,
|
||||
style: selectedWritingStyle,
|
||||
website: "0",
|
||||
connectToWeb: true,
|
||||
lang: selectedLanguage,
|
||||
pointOfView: "None",
|
||||
clientId: "",
|
||||
};
|
||||
console.log("Sending request for title with data:", titleData);
|
||||
const titleRes = await getGenerateTitle(titleData);
|
||||
setTitle(titleRes?.data?.data || "");
|
||||
console.log("Generated title:", titleRes?.data?.data);
|
||||
|
||||
const keywordsData = {
|
||||
keyword: selectedMainKeyword,
|
||||
style: selectedWritingStyle,
|
||||
website: "0",
|
||||
connectToWeb: true,
|
||||
lang: selectedLanguage,
|
||||
pointOfView: "None",
|
||||
clientId: "",
|
||||
};
|
||||
console.log("Sending request for keywords with data:", keywordsData);
|
||||
const keywordsRes = await getGenerateKeywords(keywordsData);
|
||||
setSelectedSEO(keywordsRes?.data?.data || []);
|
||||
console.log("Generated keywords:", keywordsRes?.data?.data);
|
||||
} catch (error) {
|
||||
console.error("Error during generation process:", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
} else {
|
||||
console.error("Please provide a valid main keyword.");
|
||||
}
|
||||
};
|
||||
|
||||
const doGenerateTitle = async () => {
|
||||
if (selectedMainKeyword?.length > 1) {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const titleData = {
|
||||
keyword: selectedMainKeyword,
|
||||
style: selectedWritingStyle,
|
||||
website: "0",
|
||||
connectToWeb: true,
|
||||
lang: selectedLanguage,
|
||||
pointOfView: "None",
|
||||
clientId: "",
|
||||
};
|
||||
console.log("Sending request for title with data:", titleData);
|
||||
const titleRes = await getGenerateTitle(titleData);
|
||||
setTitle(titleRes?.data?.data || "");
|
||||
console.log("Generated title:", titleRes?.data?.data);
|
||||
} catch (error) {
|
||||
console.error("Error generating title:", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
} else {
|
||||
console.error("Please provide a valid main keyword.");
|
||||
}
|
||||
};
|
||||
|
||||
const doGenerateKeyword = async () => {
|
||||
if (selectedMainKeyword?.length > 1) {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const keywordsData = {
|
||||
keyword: selectedMainKeyword,
|
||||
style: selectedWritingStyle,
|
||||
website: "0",
|
||||
connectToWeb: true,
|
||||
lang: selectedLanguage,
|
||||
pointOfView: "None",
|
||||
clientId: "",
|
||||
};
|
||||
console.log("Sending request for keywords with data:", keywordsData);
|
||||
const keywordsRes = await getGenerateKeywords(keywordsData);
|
||||
setSelectedSEO(keywordsRes?.data?.data || []);
|
||||
console.log("Generated keywords:", keywordsRes?.data?.data);
|
||||
} catch (error) {
|
||||
console.error("Error generating keywords:", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
} else {
|
||||
console.error("Please provide a valid main keyword.");
|
||||
}
|
||||
};
|
||||
|
||||
const handleGenerateArtikel = async () => {
|
||||
const request = {
|
||||
advConfig: selectedAdvConfig,
|
||||
style: selectedWritingStyle,
|
||||
website: "None",
|
||||
connectToWeb: true,
|
||||
lang: selectedLanguage,
|
||||
pointOfView: "None",
|
||||
title: title,
|
||||
imageSource: "Web",
|
||||
mainKeyword: selectedMainKeyword,
|
||||
additionalKeywords: selectedSEO,
|
||||
targetCountry: null,
|
||||
articleSize: selectedSize,
|
||||
projectId: 2,
|
||||
createdBy: roleId,
|
||||
clientId: "ngDLPPiorplznw2jTqVe3YFCz5xqKfUJ",
|
||||
};
|
||||
|
||||
const res = await generateDataArticle(request);
|
||||
close();
|
||||
|
||||
if (res.error) {
|
||||
console.error(res.message);
|
||||
return false;
|
||||
}
|
||||
|
||||
const newArticleId = res?.data?.data?.id;
|
||||
setIsGeneratedArticle(true);
|
||||
|
||||
setArticleIds((prevIds: string[]) => {
|
||||
if (prevIds.length < 5) {
|
||||
return [...prevIds, newArticleId];
|
||||
} else {
|
||||
const updatedIds = [...prevIds];
|
||||
updatedIds[4] = newArticleId;
|
||||
return updatedIds;
|
||||
}
|
||||
});
|
||||
|
||||
Cookies.set("nulisAIArticleIdTemp", JSON.stringify(articleIds));
|
||||
};
|
||||
|
||||
const handleArticleIdClick = async (id: string) => {
|
||||
const res = await getDetailArticle(id);
|
||||
const articleData = res?.data?.data;
|
||||
|
||||
const cleanArticleBody = articleData?.articleBody?.replace(
|
||||
/<img[^>]*>/g,
|
||||
""
|
||||
);
|
||||
const articleImagesData = articleData?.imagesUrl?.split(",");
|
||||
|
||||
setArticleBody(cleanArticleBody || "");
|
||||
setDetailData(articleData);
|
||||
setSelectedArticleId(id);
|
||||
setArticleImages(articleImagesData || []);
|
||||
};
|
||||
|
||||
// const handleKeyDown = (e: any) => {
|
||||
// const newTag = e.target.value.trim(); // Ambil nilai input
|
||||
// if (e.key === "Enter" && newTag) {
|
||||
|
|
@ -242,6 +426,7 @@ export default function FormImage() {
|
|||
<p className="text-red-400 text-sm">{errors.title.message}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center">
|
||||
<div className="py-3 w-full">
|
||||
<Label>Kategori</Label>
|
||||
|
|
@ -268,7 +453,228 @@ export default function FormImage() {
|
|||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="py-3">
|
||||
<div className="flex flex-row items-center gap-3 py-2">
|
||||
<Label>Bantuan AI</Label>
|
||||
<div className="flex items-center gap-3">
|
||||
<Switch
|
||||
defaultChecked={isSwitchOn}
|
||||
color="primary"
|
||||
id="c2"
|
||||
onCheckedChange={(checked: boolean) =>
|
||||
setIsSwitchOn(checked)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{isSwitchOn && (
|
||||
<div>
|
||||
<div className="flex flex-row gap-3">
|
||||
<div className="space-y-2 py-3 w-4/12">
|
||||
<Label>Bahasa</Label>
|
||||
<Select onValueChange={setSelectedLanguage}>
|
||||
<SelectTrigger size="md">
|
||||
<SelectValue placeholder="Pilih" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="id">Indonesia</SelectItem>
|
||||
<SelectItem value="en">English</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-2 py-3 w-4/12">
|
||||
<Label>Writing Style</Label>
|
||||
<Select onValueChange={setSelectedWritingStyle}>
|
||||
<SelectTrigger size="md">
|
||||
<SelectValue placeholder="Pilih" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="friendly">Friendly</SelectItem>
|
||||
<SelectItem value="profesional">
|
||||
Profesional
|
||||
</SelectItem>
|
||||
<SelectItem value="informational">
|
||||
Informational
|
||||
</SelectItem>
|
||||
<SelectItem value="neutral">Neutral</SelectItem>
|
||||
<SelectItem value="witty">Witty</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-2 py-3 w-4/12">
|
||||
<Label>Article Size</Label>
|
||||
<Select onValueChange={setSelectedSize}>
|
||||
<SelectTrigger size="md">
|
||||
<SelectValue placeholder="Pilih" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="news">
|
||||
News (300 - 900 words)
|
||||
</SelectItem>
|
||||
<SelectItem value="info">
|
||||
Info (900 - 2000 words)
|
||||
</SelectItem>
|
||||
<SelectItem value="detail">
|
||||
Detail (2000 - 5000 words)
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5">
|
||||
<div className="flex flex-row items-center gap-3 mb-3">
|
||||
<Label>Main Keyword</Label>
|
||||
<Button
|
||||
variant="outline"
|
||||
color="primary"
|
||||
onClick={doGenerateMainKeyword}
|
||||
disabled={isLoading}
|
||||
>
|
||||
{isLoading ? "Processing..." : "Proses"}
|
||||
</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
value={selectedMainKeyword}
|
||||
onChange={(e) => setSelectedMainKeyword(e.target.value)}
|
||||
placeholder="Enter Main Keyword"
|
||||
/>
|
||||
{/* )}
|
||||
/> */}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5">
|
||||
<div className="flex flex-row items-center gap-3 mb-3">
|
||||
<Label>Judul</Label>
|
||||
<Button
|
||||
variant="outline"
|
||||
color="primary"
|
||||
onClick={doGenerateTitle}
|
||||
disabled={isLoading}
|
||||
>
|
||||
{isLoading ? "Generating..." : "Generate"}
|
||||
</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
value={title}
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
placeholder="Generated Title"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5">
|
||||
<div className="flex flex-row items-center gap-3 mb-3">
|
||||
<Label>SEO</Label>
|
||||
<Button
|
||||
variant={"outline"}
|
||||
color="primary"
|
||||
onClick={doGenerateKeyword}
|
||||
disabled={isLoading}
|
||||
>
|
||||
{isLoading ? "Generating..." : "Generate"}
|
||||
</Button>
|
||||
</div>
|
||||
<p className="font-semibold">
|
||||
Kata kunci untuk disertakan dalam teks
|
||||
</p>
|
||||
<p className="text-sm">
|
||||
JIka Anda tidak Memberikan kata kunci, kami akan secara
|
||||
otomatis membuat kata kunci yang relevan dari kata kunci
|
||||
utama untuk setiap bagian dan menggunakannya untuk membuat
|
||||
artikel. Untuk menambahkan kata kunci baru, ketik ', +
|
||||
kata kunci'.
|
||||
</p>
|
||||
<div className="mt-3">
|
||||
<Textarea
|
||||
value={selectedSEO}
|
||||
onChange={(e) => setSelectedSEO(e.target.value)}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5">
|
||||
<Label>Instruksi Khusus (Optional)</Label>
|
||||
<div className="mt-3">
|
||||
<Controller
|
||||
control={control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<Textarea
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="my-5">
|
||||
<Button
|
||||
// variant={"outline"}
|
||||
color="primary"
|
||||
onClick={handleGenerateArtikel}
|
||||
>
|
||||
Generate Article
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{isGeneratedArticle && (
|
||||
<div className="mt-3 pb-0">
|
||||
{articleIds.map((id: string, index: number) => (
|
||||
<Button
|
||||
key={index}
|
||||
className={`btn m-1 ${
|
||||
selectedArticleId === id
|
||||
? "btn-warning"
|
||||
: "btn-success"
|
||||
}`}
|
||||
onClick={() => handleArticleIdClick(id)}
|
||||
variant={"outline"}
|
||||
color="success"
|
||||
>
|
||||
{id}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="pt-3">
|
||||
<div className="flex flex-row justify-between items-center">
|
||||
{selectedArticleId && (
|
||||
<a
|
||||
href={`/admin/media/${
|
||||
fileTypeId === "1"
|
||||
? "image"
|
||||
: fileTypeId === "2"
|
||||
? "video"
|
||||
: fileTypeId === "3"
|
||||
? "text"
|
||||
: "audio"
|
||||
}/update-new/${selectedArticleId}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Button
|
||||
className="mb-2"
|
||||
size="sm"
|
||||
variant={"outline"}
|
||||
color="primary"
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="">
|
||||
<Label>Deskripsi</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
|
|
@ -276,7 +682,7 @@ export default function FormImage() {
|
|||
render={({ field: { onChange, value } }) => (
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={value}
|
||||
value={articleBody || value}
|
||||
onChange={onChange}
|
||||
className="dark:text-black"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -351,6 +351,14 @@ export default function FormConvertSPIT() {
|
|||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="my-5">
|
||||
<Button
|
||||
// variant={"outline"}
|
||||
color="primary"
|
||||
>
|
||||
Content Rewrite
|
||||
</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-xl text-black">File Media</Label>
|
||||
<div className="w-full ">
|
||||
|
|
|
|||
|
|
@ -189,10 +189,10 @@ export default function FormContestDetail() {
|
|||
theme: data.theme,
|
||||
};
|
||||
|
||||
const response = await createTask(requestData);
|
||||
// const response = await createTask(requestData);
|
||||
|
||||
console.log("Form Data Submitted:", requestData);
|
||||
console.log("response", response);
|
||||
// console.log("response", response);
|
||||
|
||||
MySwal.fire({
|
||||
title: "Sukses",
|
||||
|
|
@ -201,7 +201,7 @@ export default function FormContestDetail() {
|
|||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "OK",
|
||||
}).then(() => {
|
||||
router.push("/en/contributor/task");
|
||||
router.push("/en/shared/contest");
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -369,11 +369,11 @@ export default function FormContestDetail() {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{/* <div className="mt-4">
|
||||
<Button type="submit" color="primary">
|
||||
Submit
|
||||
</Button>
|
||||
</div> */}
|
||||
<div className="mt-4">
|
||||
<Button type="submit" color="primary">
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</Card>
|
||||
|
|
|
|||
14
lib/menus.ts
14
lib/menus.ts
|
|
@ -97,13 +97,13 @@ export function getMenuList(pathname: string, t: any): Group[] {
|
|||
icon: "heroicons:credit-card",
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
href: "/contributor/content/nulis-ai",
|
||||
label: "nulis ai",
|
||||
active: pathname.includes("/content/nulisai"),
|
||||
icon: "heroicons:credit-card",
|
||||
children: [],
|
||||
},
|
||||
// {
|
||||
// href: "/contributor/content/nulis-ai",
|
||||
// label: "nulis ai",
|
||||
// active: pathname.includes("/content/nulisai"),
|
||||
// icon: "heroicons:credit-card",
|
||||
// children: [],
|
||||
// },
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
|||
Loading…
Reference in New Issue