Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod
This commit is contained in:
commit
82d2c19e02
|
|
@ -108,6 +108,66 @@ const ReportTable = () => {
|
||||||
const [previewData, setPreviewData] = React.useState<any>(null);
|
const [previewData, setPreviewData] = React.useState<any>(null);
|
||||||
const [openDateDialog, setOpenDateDialog] = React.useState(false);
|
const [openDateDialog, setOpenDateDialog] = React.useState(false);
|
||||||
const [reportDate, setReportDate] = React.useState("");
|
const [reportDate, setReportDate] = React.useState("");
|
||||||
|
const [startDate, setStartDate] = React.useState("");
|
||||||
|
const [endDate, setEndDate] = React.useState("");
|
||||||
|
|
||||||
|
// handleGenerateReport ubah sedikit
|
||||||
|
const handleGenerateReport = async () => {
|
||||||
|
if (!startDate || !endDate) {
|
||||||
|
MySwal.fire(
|
||||||
|
"Warning",
|
||||||
|
"Silakan pilih tanggal awal dan tanggal akhir terlebih dahulu",
|
||||||
|
"warning"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new Date(startDate) > new Date(endDate)) {
|
||||||
|
MySwal.fire(
|
||||||
|
"Warning",
|
||||||
|
"Tanggal awal tidak boleh lebih besar dari tanggal akhir",
|
||||||
|
"warning"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const title = `Report ${format(
|
||||||
|
new Date(startDate),
|
||||||
|
"dd-MM-yyyy"
|
||||||
|
)} - ${format(new Date(endDate), "dd-MM-yyyy")}`;
|
||||||
|
const requestData = {
|
||||||
|
title,
|
||||||
|
startDate,
|
||||||
|
endDate,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await saveReport(requestData);
|
||||||
|
if (response?.error) {
|
||||||
|
MySwal.fire(
|
||||||
|
"Error",
|
||||||
|
response?.message || "Gagal menyimpan laporan",
|
||||||
|
"error"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MySwal.fire({
|
||||||
|
title: "Sukses",
|
||||||
|
text: "Laporan berhasil dibuat.",
|
||||||
|
icon: "success",
|
||||||
|
confirmButtonColor: "#3085d6",
|
||||||
|
confirmButtonText: "OK",
|
||||||
|
}).then(() => {
|
||||||
|
fetchData();
|
||||||
|
setStartDate("");
|
||||||
|
setEndDate("");
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Generate report error:", error);
|
||||||
|
MySwal.fire("Error", "Terjadi kesalahan saat membuat laporan", "error");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handlePreview = (id: string) => {
|
const handlePreview = (id: string) => {
|
||||||
const url = `https://mediahub.polri.go.id/api/v2/media/report/view?id=${id}`;
|
const url = `https://mediahub.polri.go.id/api/v2/media/report/view?id=${id}`;
|
||||||
|
|
@ -244,49 +304,6 @@ const ReportTable = () => {
|
||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
|
|
||||||
const handleGenerateReport = async () => {
|
|
||||||
if (!reportDate) {
|
|
||||||
MySwal.fire(
|
|
||||||
"Warning",
|
|
||||||
"Silakan pilih tanggal laporan terlebih dahulu",
|
|
||||||
"warning"
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const title = `Report ${format(new Date(reportDate), "dd-MM-yyyy")}`;
|
|
||||||
const requestData = {
|
|
||||||
title,
|
|
||||||
date: reportDate,
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await saveReport(requestData);
|
|
||||||
if (response?.error) {
|
|
||||||
MySwal.fire(
|
|
||||||
"Error",
|
|
||||||
response?.message || "Gagal menyimpan laporan",
|
|
||||||
"error"
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MySwal.fire({
|
|
||||||
title: "Sukses",
|
|
||||||
text: "Laporan berhasil dibuat.",
|
|
||||||
icon: "success",
|
|
||||||
confirmButtonColor: "#3085d6",
|
|
||||||
confirmButtonText: "OK",
|
|
||||||
}).then(() => {
|
|
||||||
fetchData();
|
|
||||||
setReportDate("");
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Generate report error:", error);
|
|
||||||
MySwal.fire("Error", "Terjadi kesalahan saat membuat laporan", "error");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Dialog open={openPreview} onOpenChange={setOpenPreview}>
|
<Dialog open={openPreview} onOpenChange={setOpenPreview}>
|
||||||
|
|
@ -388,13 +405,13 @@ const ReportTable = () => {
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent
|
<DropdownMenuContent
|
||||||
align="end"
|
align="end"
|
||||||
className="w-64 h-[200px] overflow-y-auto"
|
className="w-64 h-fit overflow-y-auto"
|
||||||
>
|
>
|
||||||
<div className="flex flex-row justify-between my-1 mx-1">
|
<div className="flex flex-row justify-between my-1 mx-1">
|
||||||
<p>Filter</p>
|
<p>Filter</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx-2 my-1">
|
<div className="mx-2 my-1">
|
||||||
<Label>{t("date", { defaultValue: "Date" })}</Label>
|
<Label>Tanggal Generate</Label>
|
||||||
<Input
|
<Input
|
||||||
type="date"
|
type="date"
|
||||||
value={dateFilter}
|
value={dateFilter}
|
||||||
|
|
@ -411,8 +428,8 @@ const ReportTable = () => {
|
||||||
className="max-w-sm"
|
className="max-w-sm"
|
||||||
/>
|
/>
|
||||||
</div> */}
|
</div> */}
|
||||||
<Label className="ml-2 mt-2">Status</Label>
|
{/* <Label className="ml-2 mt-2">Status</Label> */}
|
||||||
<div className="flex items-center px-4 py-1">
|
{/* <div className="flex items-center px-4 py-1">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
id="status-1"
|
id="status-1"
|
||||||
|
|
@ -423,8 +440,8 @@ const ReportTable = () => {
|
||||||
<label htmlFor="status-1" className="text-sm">
|
<label htmlFor="status-1" className="text-sm">
|
||||||
{t("wait-review", { defaultValue: "Wait Review" })}
|
{t("wait-review", { defaultValue: "Wait Review" })}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div> */}
|
||||||
<div className="flex items-center px-4 py-1">
|
{/* <div className="flex items-center px-4 py-1">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
id="status-2"
|
id="status-2"
|
||||||
|
|
@ -435,7 +452,7 @@ const ReportTable = () => {
|
||||||
<label htmlFor="status-2" className="text-sm">
|
<label htmlFor="status-2" className="text-sm">
|
||||||
{t("acc", { defaultValue: "Acc" })}
|
{t("acc", { defaultValue: "Acc" })}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div> */}
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -525,16 +542,27 @@ const ReportTable = () => {
|
||||||
<Dialog open={openDateDialog} onOpenChange={setOpenDateDialog}>
|
<Dialog open={openDateDialog} onOpenChange={setOpenDateDialog}>
|
||||||
<DialogContent className="sm:max-w-md">
|
<DialogContent className="sm:max-w-md">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Pilih Tanggal Laporan</DialogTitle>
|
<DialogTitle>Pilih Rentang Tanggal Laporan</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<Label htmlFor="reportDate">Tanggal</Label>
|
<div>
|
||||||
<Input
|
<Label htmlFor="startDate">Tanggal Awal</Label>
|
||||||
id="reportDate"
|
<Input
|
||||||
type="date"
|
id="startDate"
|
||||||
value={reportDate}
|
type="date"
|
||||||
onChange={(e) => setReportDate(e.target.value)}
|
value={startDate}
|
||||||
/>
|
onChange={(e) => setStartDate(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Label htmlFor="endDate">Tanggal Akhir</Label>
|
||||||
|
<Input
|
||||||
|
id="endDate"
|
||||||
|
type="date"
|
||||||
|
value={endDate}
|
||||||
|
onChange={(e) => setEndDate(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div className="flex justify-end gap-2">
|
<div className="flex justify-end gap-2">
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
|
|
|
||||||
|
|
@ -300,7 +300,7 @@ export default function ContentBlast(props: { type: string }) {
|
||||||
Untuk melihat Email Terkirim silahkan cek menu “Sent”!
|
Untuk melihat Email Terkirim silahkan cek menu “Sent”!
|
||||||
</div>
|
</div>
|
||||||
<DialogFooter className="flex justify-center">
|
<DialogFooter className="flex justify-center">
|
||||||
<Link
|
{/* <Link
|
||||||
href={`/admin/broadcast/campaign-list/detail/${
|
href={`/admin/broadcast/campaign-list/detail/${
|
||||||
form.getValues("selected")[0]?.id
|
form.getValues("selected")[0]?.id
|
||||||
}`}
|
}`}
|
||||||
|
|
@ -308,7 +308,7 @@ export default function ContentBlast(props: { type: string }) {
|
||||||
<Button type="button" color="success">
|
<Button type="button" color="success">
|
||||||
Menu "Sent"
|
Menu "Sent"
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link> */}
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ import { ChevronDownIcon } from "lucide-react";
|
||||||
import { getOperatorUser } from "@/service/management-user/management-user";
|
import { getOperatorUser } from "@/service/management-user/management-user";
|
||||||
import makeAnimated from "react-select/animated";
|
import makeAnimated from "react-select/animated";
|
||||||
import Select, { ActionMeta, MultiValue } from "react-select";
|
import Select, { ActionMeta, MultiValue } from "react-select";
|
||||||
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
|
|
||||||
interface Option {
|
interface Option {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
@ -114,6 +115,7 @@ export default function FormQuestionsForward() {
|
||||||
const [selectedOperator, setSelectedOperator] = useState<string[]>([]);
|
const [selectedOperator, setSelectedOperator] = useState<string[]>([]);
|
||||||
const [options, setOptions] = useState<Option[]>([]);
|
const [options, setOptions] = useState<Option[]>([]);
|
||||||
const animatedComponent = makeAnimated();
|
const animatedComponent = makeAnimated();
|
||||||
|
const [isCollaboration, setIsCollaboration] = useState(false);
|
||||||
const [selectedOption, setSelectedOption] = useState<Option[]>([]);
|
const [selectedOption, setSelectedOption] = useState<Option[]>([]);
|
||||||
const [replies, setReplies] = useState([
|
const [replies, setReplies] = useState([
|
||||||
{
|
{
|
||||||
|
|
@ -199,6 +201,7 @@ export default function FormQuestionsForward() {
|
||||||
operatorTeam: selectedOperator.join(","),
|
operatorTeam: selectedOperator.join(","),
|
||||||
isEscalation: true,
|
isEscalation: true,
|
||||||
communicationTeam: selectedOption.map((item) => item.id).join(","),
|
communicationTeam: selectedOption.map((item) => item.id).join(","),
|
||||||
|
isCollaboration: isCollaboration,
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await saveTicketsQuestion(payload);
|
const response = await saveTicketsQuestion(payload);
|
||||||
|
|
@ -453,6 +456,14 @@ export default function FormQuestionsForward() {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-row gap-2 px-3 py-3">
|
||||||
|
<Label className="">Bagikan Untuk Kolaborasi</Label>
|
||||||
|
<Checkbox
|
||||||
|
checked={isCollaboration}
|
||||||
|
onCheckedChange={(e: boolean) => setIsCollaboration(e)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="flex justify-end mt-3 mr-3 py-3">
|
<div className="flex justify-end mt-3 mr-3 py-3">
|
||||||
<Button type="submit" color="primary">
|
<Button type="submit" color="primary">
|
||||||
Simpan
|
Simpan
|
||||||
|
|
|
||||||
|
|
@ -792,6 +792,117 @@ export default function FormConvertSPIT() {
|
||||||
|
|
||||||
{/* Content Editor */}
|
{/* Content Editor */}
|
||||||
<Card>
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle className="flex items-center gap-2">
|
||||||
|
<Edit3 className="h-5 w-5" />
|
||||||
|
Content Editor
|
||||||
|
</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="space-y-8">
|
||||||
|
{/* Original Content */}
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label className="text-lg text-black">Original Content</Label>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="contentDescription"
|
||||||
|
render={({ field }) => (
|
||||||
|
<CustomEditor
|
||||||
|
onChange={field.onChange}
|
||||||
|
initialData={field.value}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Content Rewrite */}
|
||||||
|
<div className="space-y-4">
|
||||||
|
<Label className="text-lg text-black">
|
||||||
|
Rewritten Content
|
||||||
|
</Label>
|
||||||
|
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label>Writing Style</Label>
|
||||||
|
<Select
|
||||||
|
value={selectedWritingStyle}
|
||||||
|
onValueChange={setSelectedWritingStyle}
|
||||||
|
>
|
||||||
|
<SelectTrigger className="w-48">
|
||||||
|
<SelectValue placeholder="Select style" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
{WRITING_STYLES.map((style) => (
|
||||||
|
<SelectItem key={style.value} value={style.value}>
|
||||||
|
{style.label}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
onClick={handleRewriteClick}
|
||||||
|
disabled={
|
||||||
|
isGeneratingRewrite || !detail?.contentDescription
|
||||||
|
}
|
||||||
|
className="bg-blue-600 hover:bg-blue-700"
|
||||||
|
>
|
||||||
|
{isGeneratingRewrite ? (
|
||||||
|
<Loader2 className="h-4 w-4 mr-2 animate-spin" />
|
||||||
|
) : (
|
||||||
|
<Edit3 className="h-4 w-4 mr-2" />
|
||||||
|
)}
|
||||||
|
Generate Rewrite
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{showRewriteEditor && (
|
||||||
|
<div className="space-y-4">
|
||||||
|
{articleIds.length > 0 && (
|
||||||
|
<div className="flex gap-2">
|
||||||
|
{articleIds.map((articleId, index) => (
|
||||||
|
<Button
|
||||||
|
key={articleId}
|
||||||
|
type="button"
|
||||||
|
variant={
|
||||||
|
selectedArticleId === articleId
|
||||||
|
? "default"
|
||||||
|
: "outline"
|
||||||
|
}
|
||||||
|
size="sm"
|
||||||
|
onClick={() => handleArticleSelect(articleId)}
|
||||||
|
disabled={isLoadingRewrite}
|
||||||
|
>
|
||||||
|
{isLoadingRewrite &&
|
||||||
|
selectedArticleId === articleId && (
|
||||||
|
<Loader2 className="h-4 w-4 mr-2 animate-spin" />
|
||||||
|
)}
|
||||||
|
Narrative {index + 1}
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label>Rewritten Content</Label>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="contentRewriteDescription"
|
||||||
|
render={({ field }) => (
|
||||||
|
<CustomEditor
|
||||||
|
onChange={field.onChange}
|
||||||
|
initialData={articleBody || field.value}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
{/* <Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center gap-2">
|
<CardTitle className="flex items-center gap-2">
|
||||||
<Edit3 className="h-5 w-5" />
|
<Edit3 className="h-5 w-5" />
|
||||||
|
|
@ -817,7 +928,7 @@ export default function FormConvertSPIT() {
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
|
|
||||||
{/* Original Content */}
|
{/* Original Content */}
|
||||||
{selectedFileType === "original" && (
|
{/* {selectedFileType === "original" && (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>Content Description</Label>
|
<Label>Content Description</Label>
|
||||||
<Controller
|
<Controller
|
||||||
|
|
@ -831,10 +942,10 @@ export default function FormConvertSPIT() {
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)} */}
|
||||||
|
|
||||||
{/* Content Rewrite */}
|
{/* Content Rewrite */}
|
||||||
{selectedFileType === "rewrite" && (
|
{/* {selectedFileType === "rewrite" && (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
|
|
@ -917,7 +1028,7 @@ export default function FormConvertSPIT() {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card> */}
|
||||||
|
|
||||||
{/* Media Files */}
|
{/* Media Files */}
|
||||||
{detailThumb.length > 0 && (
|
{detailThumb.length > 0 && (
|
||||||
|
|
@ -1075,7 +1186,9 @@ export default function FormConvertSPIT() {
|
||||||
|
|
||||||
<div className="flex-1 space-y-3">
|
<div className="flex-1 space-y-3">
|
||||||
<p className="font-medium text-sm">
|
<p className="font-medium text-sm">
|
||||||
{file.fileName || file.contentFileName || `File ${file.contentId}`}
|
{file.fileName ||
|
||||||
|
file.contentFileName ||
|
||||||
|
`File ${file.contentId}`}
|
||||||
</p>
|
</p>
|
||||||
<div className="flex flex-wrap gap-3">
|
<div className="flex flex-wrap gap-3">
|
||||||
{PLACEMENT_OPTIONS.map((option) => (
|
{PLACEMENT_OPTIONS.map((option) => (
|
||||||
|
|
@ -1273,7 +1386,6 @@ export default function FormConvertSPIT() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// "use client";
|
// "use client";
|
||||||
// import React, { ChangeEvent, useEffect, useRef, useState } from "react";
|
// import React, { ChangeEvent, useEffect, useRef, useState } from "react";
|
||||||
// import { useForm, Controller } from "react-hook-form";
|
// import { useForm, Controller } from "react-hook-form";
|
||||||
|
|
@ -2486,5 +2598,3 @@ export default function FormConvertSPIT() {
|
||||||
// </div>
|
// </div>
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,10 +92,19 @@ export default function InfoLainnyaModal({
|
||||||
className="max-h-[300px] w-auto object-contain border rounded"
|
className="max-h-[300px] w-auto object-contain border rounded"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
// <iframe
|
||||||
|
// src={getIframeUrl(currentFile?.fileUrl || "")}
|
||||||
|
// title={`Lampiran ${currentIndex + 1}`}
|
||||||
|
// className="w-full max-w-2xl h-[300px] border rounded"
|
||||||
|
// onError={(e) => {
|
||||||
|
// (e.target as HTMLIFrameElement).style.display = "none";
|
||||||
|
// }}
|
||||||
|
// />
|
||||||
<iframe
|
<iframe
|
||||||
src={getIframeUrl(currentFile?.fileUrl || "")}
|
src={getIframeUrl(currentFile?.fileUrl || "")}
|
||||||
title={`Lampiran ${currentIndex + 1}`}
|
title={`Lampiran ${currentIndex + 1}`}
|
||||||
className="w-full max-w-2xl h-[300px] border rounded"
|
className="w-full max-w-2xl h-[500px] rounded overflow-hidden"
|
||||||
|
scrolling="no"
|
||||||
onError={(e) => {
|
onError={(e) => {
|
||||||
(e.target as HTMLIFrameElement).style.display = "none";
|
(e.target as HTMLIFrameElement).style.display = "none";
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue