feat:scheduled create article
This commit is contained in:
parent
ec2e0ef1b8
commit
f2e3d7f731
|
|
@ -6,18 +6,21 @@ import Cookies from "js-cookie";
|
|||
import React, { useEffect, useState } from "react";
|
||||
|
||||
export default function AuthPage() {
|
||||
const isAuthenticated = Cookies.get("is_authenticated") || "false";
|
||||
// const isAuthenticated = Cookies.get("is_authenticated") || "false";
|
||||
|
||||
console.log("isAuthenticated : ", isAuthenticated);
|
||||
// console.log("isAuthenticated : ", isAuthenticated);
|
||||
|
||||
const [hasMounted, setHasMounted] = useState(false);
|
||||
// const [hasMounted, setHasMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setHasMounted(true);
|
||||
}, []);
|
||||
// useEffect(() => {
|
||||
// setHasMounted(true);
|
||||
// }, []);
|
||||
|
||||
// Render
|
||||
if (!hasMounted) return null;
|
||||
// // Render
|
||||
// if (!hasMounted) return null;
|
||||
|
||||
return isAuthenticated == "true" ? <Login /> : <QudoLogin />;
|
||||
return <Login />;
|
||||
|
||||
// isAuthenticated == "true" ?
|
||||
// : <QudoLogin />;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,12 @@
|
|||
"use client";
|
||||
import { FormEvent, Fragment, useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
FormEvent,
|
||||
Fragment,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
|
|
@ -24,9 +31,15 @@ import makeAnimated from "react-select/animated";
|
|||
import {
|
||||
Checkbox,
|
||||
Chip,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalContent,
|
||||
ModalFooter,
|
||||
ModalHeader,
|
||||
Select,
|
||||
SelectItem,
|
||||
SelectSection,
|
||||
useDisclosure,
|
||||
} from "@nextui-org/react";
|
||||
import GenerateSingleArticleForm from "./generate-ai-single-form";
|
||||
import { htmlToString } from "@/utils/global";
|
||||
|
|
@ -39,6 +52,7 @@ import {
|
|||
updateManualArticle,
|
||||
} from "@/service/generate-article";
|
||||
import GenerateContentRewriteForm from "./generate-ai-content-rewrite-form";
|
||||
import Datepicker from "react-tailwindcss-datepicker";
|
||||
|
||||
const CustomEditor = dynamic(
|
||||
() => {
|
||||
|
|
@ -92,6 +106,8 @@ const createArticleSchema = z.object({
|
|||
});
|
||||
|
||||
export default function CreateArticleForm() {
|
||||
const { isOpen, onOpen, onOpenChange } = useDisclosure();
|
||||
|
||||
const animatedComponents = makeAnimated();
|
||||
const MySwal = withReactContent(Swal);
|
||||
const router = useRouter();
|
||||
|
|
@ -108,7 +124,16 @@ export default function CreateArticleForm() {
|
|||
const [filesValidation, setFileValidation] = useState("");
|
||||
const [diseData, setDiseData] = useState<DiseData>();
|
||||
const [selectedWritingType, setSelectedWritingType] = useState("single");
|
||||
const [status, setStatus] = useState<"publish" | "draft">("publish");
|
||||
const [status, setStatus] = useState<"publish" | "draft" | "scheduled">(
|
||||
"publish"
|
||||
);
|
||||
const [isScheduled, setIsScheduled] = useState(false);
|
||||
const [timeValue, setTimeValue] = useState("");
|
||||
|
||||
const [startDateValue, setStartDateValue] = useState({
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
});
|
||||
|
||||
const { getRootProps, getInputProps } = useDropzone({
|
||||
onDrop: (acceptedFiles) => {
|
||||
|
|
@ -132,7 +157,7 @@ export default function CreateArticleForm() {
|
|||
register,
|
||||
control,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
formState: { errors, isValid },
|
||||
setValue,
|
||||
getValues,
|
||||
watch,
|
||||
|
|
@ -177,8 +202,7 @@ export default function CreateArticleForm() {
|
|||
}
|
||||
} else {
|
||||
setThumbnailValidation("");
|
||||
setFileValidation("Required");
|
||||
|
||||
setFileValidation("");
|
||||
MySwal.fire({
|
||||
title: "Simpan Data",
|
||||
text: "",
|
||||
|
|
@ -426,14 +450,6 @@ export default function CreateArticleForm() {
|
|||
setValue("tags", uniqueArray as [string, ...string[]]);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log("seklec", selectedMainImage);
|
||||
console.log("seklssssec", files);
|
||||
if (selectedMainImage) {
|
||||
console.log("filll", files[selectedMainImage]);
|
||||
}
|
||||
}, [selectedMainImage]);
|
||||
|
||||
return (
|
||||
<form
|
||||
className="flex flex-col lg:flex-row gap-8 text-black"
|
||||
|
|
@ -750,12 +766,59 @@ export default function CreateArticleForm() {
|
|||
{errors?.tags && (
|
||||
<p className="text-red-400 text-sm mb-3">{errors.tags?.message}</p>
|
||||
)}
|
||||
<div className="flex flex-col gap-2 mt-3">
|
||||
<Switch isSelected={isScheduled} onValueChange={setIsScheduled}>
|
||||
Publish dengan Jadwal
|
||||
</Switch>
|
||||
{isScheduled && (
|
||||
<div className="flex flex-col lg:flex-row gap-3">
|
||||
<div className="w-full lg:w-[140px] flex flex-col gal-2 ">
|
||||
<p className="text-sm">Tanggal</p>
|
||||
<Datepicker
|
||||
value={startDateValue}
|
||||
displayFormat="DD/MM/YYYY"
|
||||
popoverDirection="down"
|
||||
asSingle={true}
|
||||
useRange={false}
|
||||
onChange={(e: any) => setStartDateValue(e)}
|
||||
inputClassName="z-50 w-full text-xs lg:text-sm bg-white dark bg-black border-1 border-gray-200 px-2 py-[6px] rounded-sm lg:rounded-lg h-[30px] lg:h-[40px] text-gray-600 dark:text-gray-300"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-[140px] flex flex-col gal-2 ">
|
||||
<p className="text-sm">Waktu</p>
|
||||
<Input
|
||||
type="time"
|
||||
value={timeValue}
|
||||
onValueChange={setTimeValue}
|
||||
variant="bordered"
|
||||
className="w-full"
|
||||
classNames={{
|
||||
input: "h-[30px]",
|
||||
mainWrapper: ["bg-white !h-[30px] lg:h-[40px]"],
|
||||
innerWrapper: "!h-[30px] lg:h-[40px]",
|
||||
inputWrapper: [
|
||||
"border-1 rounded-lg !h-[30px] lg:h-[40px]",
|
||||
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
|
||||
],
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-row justify-end gap-3">
|
||||
<Button
|
||||
color="primary"
|
||||
type="submit"
|
||||
onClick={() => setStatus("publish")}
|
||||
isDisabled={
|
||||
(isScheduled && startDateValue.startDate == null) ||
|
||||
(isScheduled && timeValue == "")
|
||||
}
|
||||
onClick={() =>
|
||||
isScheduled ? setStatus("scheduled") : setStatus("publish")
|
||||
}
|
||||
>
|
||||
Publish
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -68,11 +68,11 @@ export default function NavbarHumas(props: { size: string }) {
|
|||
const language = storedLanguage((state) => state.locale);
|
||||
const setLanguage = storedLanguage((state) => state.setLocale);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isAuthenticated) {
|
||||
onLogout();
|
||||
}
|
||||
}, [token]);
|
||||
// useEffect(() => {
|
||||
// if (!isAuthenticated) {
|
||||
// onLogout();
|
||||
// }
|
||||
// }, [token]);
|
||||
|
||||
const onLogout = () => {
|
||||
Object.keys(Cookies.get()).forEach((cookieName) => {
|
||||
|
|
|
|||
|
|
@ -68,6 +68,15 @@ const dummyTopPages = [
|
|||
},
|
||||
];
|
||||
|
||||
const dummyViz = {
|
||||
todayPost: 10,
|
||||
weeklyPost: 56,
|
||||
totalPost: 223,
|
||||
totalView: 422,
|
||||
totalShare: 126,
|
||||
totalComment: 67,
|
||||
};
|
||||
|
||||
const dummyPostCount = [
|
||||
{ id: 1, name: "Polda Sumatera Utara", count: 132 },
|
||||
{ id: 2, name: "Polda Metro Jaya", count: 128 },
|
||||
|
|
@ -210,10 +219,12 @@ export default function DashboardContainer() {
|
|||
</div>
|
||||
<div className="flex flex-row gap-5">
|
||||
<p className="text-lg font-semibold">
|
||||
4 Post <span className="text-sm font-normal">Hari ini</span>
|
||||
{dummyViz.todayPost} Post{" "}
|
||||
<span className="text-sm font-normal">Hari ini</span>
|
||||
</p>
|
||||
<p className="text-lg font-semibold">
|
||||
12 Post <span className="text-sm font-normal">Minggu ini</span>
|
||||
{dummyViz.weeklyPost} Post{" "}
|
||||
<span className="text-sm font-normal">Minggu ini</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -223,28 +234,28 @@ export default function DashboardContainer() {
|
|||
<DashboardSpeecIcon />
|
||||
</div>
|
||||
<div className="">Total post</div>
|
||||
<div className="font-semibold text-lg">121</div>
|
||||
<div className="font-semibold text-lg">{dummyViz.totalPost}</div>
|
||||
</div>
|
||||
<div className="w-full lg:w-[15%] h-[160px] shadow-md bg-white dark:bg-[#18181b] flex flex-col justify-center items-center rounded-lg">
|
||||
<div className="h-1/2 flex items-center justify-center">
|
||||
<DashboardConnectIcon />
|
||||
</div>
|
||||
<div className="">Total views</div>
|
||||
<div className="font-semibold text-lg">154</div>
|
||||
<div className="font-semibold text-lg">{dummyViz.totalView}</div>
|
||||
</div>
|
||||
<div className="w-full lg:w-[15%] h-[160px] shadow-md bg-white dark:bg-[#18181b] flex flex-col justify-center items-center rounded-lg">
|
||||
<div className="h-1/2 flex items-center justify-center">
|
||||
<DashboardShareIcon />
|
||||
</div>
|
||||
<div className="">Total share</div>
|
||||
<div className="font-semibold text-lg">154</div>
|
||||
<div className="font-semibold text-lg">{dummyViz.totalShare}</div>
|
||||
</div>
|
||||
<div className="w-full lg:w-[15%] h-[160px] shadow-md bg-white dark:bg-[#18181b] flex flex-col justify-center items-center rounded-lg">
|
||||
<div className="h-1/2 flex items-center justify-center">
|
||||
<DashboardCommentIcon size={50} />
|
||||
</div>
|
||||
<div className="">Total comment</div>
|
||||
<div className="font-semibold text-lg">530</div>
|
||||
<div className="font-semibold text-lg">{dummyViz.totalComment}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full flex flex-col lg:flex-row gap-6 justify-center ">
|
||||
|
|
|
|||
Loading…
Reference in New Issue