feat:scheduled create article

This commit is contained in:
Rama Priyanto 2025-02-12 12:07:28 +07:00
parent ec2e0ef1b8
commit f2e3d7f731
4 changed files with 111 additions and 34 deletions

View File

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

View File

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

View File

@ -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) => {

View File

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