Compare commits

..

No commits in common. "6e3d01cdc0acbeeaa1944f5c41d0fe377e20f5b4" and "c530639470217dd6029f613bdd97187d330f264e" have entirely different histories.

6 changed files with 57 additions and 214 deletions

View File

@ -25,7 +25,6 @@ import { useToast } from "@/components/ui/use-toast";
import CustomPagination from "@/components/table/custom-pagination"; import CustomPagination from "@/components/table/custom-pagination";
import { listDataMedia } from "@/service/service/broadcast/broadcast"; import { listDataMedia } from "@/service/service/broadcast/broadcast";
import { setBanner } from "@/service/service/settings/settings"; import { setBanner } from "@/service/service/settings/settings";
import { listArticles } from "@/service/landing/landing";
const ContentListBanner = () => { const ContentListBanner = () => {
const router = useRouter(); const router = useRouter();
@ -65,7 +64,7 @@ const ContentListBanner = () => {
); );
setBannerCount(banners?.length || 0); setBannerCount(banners?.length || 0);
// setBannerCount(data?.length || 0); setBannerCount(data?.length || 0);
} catch (error) { } catch (error) {
console.error("Error fetching banner count:", error); console.error("Error fetching banner count:", error);
} }
@ -119,43 +118,38 @@ const ContentListBanner = () => {
try { try {
loading(); loading();
const res = await listArticles( const res = await listDataMedia(
page, page - 1,
Number(showData), showData,
1, searchQuery,
undefined, categoryFilter?.sort().join(","),
undefined, statusFilter?.sort().join(","),
"createdAt",
"",
); );
console.log("RES ARTICLES:", res); const rawData = res?.data?.data;
let articlesData: any[] = []; const contentData = Array.isArray(rawData?.content)
? rawData.content
: [];
if (res?.error) { contentData.forEach((item: any, index: number) => {
articlesData = []; item.no = (page - 1) * Number(showData) + index + 1;
} else { });
articlesData = res?.data?.data || [];
}
const contentData = articlesData.map((item: any, index: number) => ({
...item,
no: (page - 1) * Number(showData) + index + 1,
smallThumbnailLink: item.thumbnailUrl, // penting
}));
setData(contentData); setData(contentData);
setTotalData(contentData.length); setTotalData(rawData?.totalElements ?? 0);
setTotalPage(1); // sementara kalau belum ada totalPages setTotalPage(rawData?.totalPages ?? 1);
close(); close();
} catch (error) { } catch (error) {
close(); close();
console.error("Error fetching banner data:", error); console.error("Error fetching banner data:", error);
setData([]); setData([]);
setTotalData(0);
setTotalPage(1);
} }
} }
// async function fetchData() { // async function fetchData() {
// try { // try {
// loading(); // loading();
@ -216,31 +210,20 @@ const ContentListBanner = () => {
} }
}; };
// const handleSelect = (id: number) => { const handleSelect = (id: number) => {
// setSelectedItems((prev) =>
// prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id],
// );
// };
const handleSelect = (id: number, checked: boolean) => {
setSelectedItems((prev) => setSelectedItems((prev) =>
checked ? [...prev, id] : prev.filter((item) => item !== id), prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id],
); );
}; };
// const handleSelectAll = () => { const handleSelectAll = () => {
// if (selectedItems.length === data.length) { if (selectedItems.length === data.length) {
// setSelectedItems([]);
// } else {
// setSelectedItems(data.map((item: any) => Number(item.id)));
// }
// };
const handleSelectAll = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.checked) {
setSelectedItems(data.map((item: any) => Number(item.id)));
} else {
setSelectedItems([]); setSelectedItems([]);
} else {
setSelectedItems(data.map((item: any) => Number(item.id)));
} }
}; };
const { toast } = useToast(); const { toast } = useToast();
const handleBanner = async (ids: number[]) => { const handleBanner = async (ids: number[]) => {
@ -427,15 +410,10 @@ const ContentListBanner = () => {
{/* Header select all + action */} {/* Header select all + action */}
<div className="flex items-center justify-between mb-4"> <div className="flex items-center justify-between mb-4">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<input <Checkbox
type="checkbox"
checked={selectedItems.length === data.length && data.length > 0}
onChange={handleSelectAll}
/>
{/* <Checkbox
checked={selectedItems.length === data.length} checked={selectedItems.length === data.length}
onCheckedChange={handleSelectAll} onCheckedChange={handleSelectAll}
/> */} />
<span className="text-black dark:text-white">Pilih Semua</span> <span className="text-black dark:text-white">Pilih Semua</span>
</div> </div>
{selectedItems.length > 0 && ( {selectedItems.length > 0 && (
@ -453,14 +431,9 @@ const ContentListBanner = () => {
className="relative rounded-lg shadow-md overflow-hidden border border-gray-200" className="relative rounded-lg shadow-md overflow-hidden border border-gray-200"
> >
<div className="absolute top-2 left-2 z-10"> <div className="absolute top-2 left-2 z-10">
{/* <Checkbox <Checkbox
checked={selectedItems.includes(item.id)} checked={selectedItems.includes(item.id)}
onCheckedChange={() => handleSelect(item.id)} onCheckedChange={() => handleSelect(item.id)}
/> */}
<input
type="checkbox"
checked={selectedItems.includes(item.id)}
onChange={(e) => handleSelect(item.id, e.target.checked)}
/> />
</div> </div>
<img <img

View File

@ -88,16 +88,12 @@ export default function SignUp() {
return; return;
} }
if (role === "umum") { // Umum dan Jurnalis → gunakan API createUser
if (role === "umum" || role === "jurnalis") {
await handleCreateUserUmum(e); await handleCreateUserUmum(e);
return; return;
} }
if (role === "jurnalis") {
await handleCreateUserJurnalis(e);
return;
}
// Kontributor (sementara ikut umum) // Kontributor (sementara ikut umum)
if (role === "kontributor") { if (role === "kontributor") {
await handleCreateUserKontributor(e); await handleCreateUserKontributor(e);
@ -229,10 +225,10 @@ export default function SignUp() {
MySwal.fire("Peringatan", "Password minimal 8 karakter", "warning"); MySwal.fire("Peringatan", "Password minimal 8 karakter", "warning");
return; return;
} }
// if (!userLevelId || !userRoleId) { if (!userLevelId || !userRoleId) {
// MySwal.fire("Peringatan", "Level dan Role wajib diisi", "warning"); MySwal.fire("Peringatan", "Level dan Role wajib diisi", "warning");
// return; return;
// } }
// ✅ Generate username otomatis // ✅ Generate username otomatis
const autoUsername = const autoUsername =
@ -284,98 +280,6 @@ export default function SignUp() {
} }
}; };
const handleCreateUserJurnalis = async (e: React.FormEvent) => {
e.preventDefault();
// ✅ VALIDASI
if (!fullname.trim()) {
MySwal.fire("Peringatan", "Nama lengkap wajib diisi", "warning");
return;
}
if (!validateEmail(email)) {
MySwal.fire("Peringatan", "Email tidak valid", "warning");
return;
}
if (!validatePassword(password)) {
MySwal.fire("Peringatan", "Password minimal 8 karakter", "warning");
return;
}
if (!membershipType) {
MySwal.fire("Peringatan", "Jenis keanggotaan wajib diisi", "warning");
return;
}
if (!certNumber.trim()) {
MySwal.fire("Peringatan", "Nomor sertifikasi wajib diisi", "warning");
return;
}
// ✅ GENERATE USERNAME
const autoUsername =
fullname.trim().replace(/\s+/g, "-").toLowerCase() || email.split("@")[0];
if (!validateUsername(autoUsername)) {
MySwal.fire("Peringatan", "Username tidak valid", "warning");
return;
}
// ✅ PAYLOAD (SUDAH DISESUAIKAN BACKEND)
const payload = {
address: "",
clientId: "78356d32-52fa-4dfc-b836-6cebf4e3eead",
dateOfBirth: "",
email,
fullName: fullname,
genderType: "",
identityGroup: "",
identityGroupNumber: "",
identityNumber: certNumber, // 🔥 penting
identityType: "KTP",
lastEducation: "",
password,
phoneNumber: "08123456789", // 🔥 jangan kosong dulu
userLevelId: 1,
userRoleId: 3, // 🔥 pastikan ini role jurnalis
username: autoUsername + "-" + Date.now(),
workType: membershipType.toUpperCase(),
};
console.log("📦 PAYLOAD JURNALIS:", payload);
try {
setIsLoading(true);
const res = await createUser(payload);
if (res?.error) {
MySwal.fire("Gagal", res?.message || "Gagal mendaftar", "error");
} else {
MySwal.fire({
title: "Berhasil!",
text: "Akun jurnalis berhasil dibuat",
icon: "success",
showConfirmButton: false,
timer: 2000,
});
setTimeout(() => router.push("/auth"), 2000);
}
} catch (err) {
console.error("❌ ERROR JURNALIS:", err);
MySwal.fire(
"Error",
"Terjadi kesalahan server saat registrasi jurnalis",
"error",
);
} finally {
setIsLoading(false);
}
};
const validateTenantForm = () => { const validateTenantForm = () => {
const errors: any = {}; const errors: any = {};
@ -688,13 +592,13 @@ export default function SignUp() {
/> />
{/* Email */} {/* Email */}
{/* <Input <Input
type="email" type="email"
required required
placeholder="Email" placeholder="Email"
value={email} value={email}
onChange={(e) => setEmail(e.target.value)} onChange={(e) => setEmail(e.target.value)}
/> */} />
{/* Password */} {/* Password */}
<div className="relative"> <div className="relative">
@ -751,25 +655,6 @@ export default function SignUp() {
{/* Jurnalis: Select Keanggotaan */} {/* Jurnalis: Select Keanggotaan */}
{role === "jurnalis" && ( {role === "jurnalis" && (
<div className="mb-4 space-y-4"> <div className="mb-4 space-y-4">
{/* Nama Lengkap */}
<Input
type="text"
required
placeholder="Nama Lengkap"
value={fullname}
onChange={(e) => setFullname(e.target.value)}
/>
{/* Username (auto generated) */}
<Input
type="text"
placeholder="Username (otomatis dari nama)"
value={username}
readOnly
className="bg-gray-100 text-gray-700 cursor-not-allowed"
/>
{/* Jenis Keanggotaan */}
<select <select
required required
className="w-full border border-gray-300 rounded-md p-2 text-sm" className="w-full border border-gray-300 rounded-md p-2 text-sm"
@ -777,11 +662,17 @@ export default function SignUp() {
onChange={(e) => setMembershipType(e.target.value)} onChange={(e) => setMembershipType(e.target.value)}
> >
<option value="">Pilih jenis keanggotaan</option> <option value="">Pilih jenis keanggotaan</option>
<option value="pwi">PWI</option> <option value="pwi">
<option value="ijti">IJTI</option> PWI (Persatuan Wartawan Indonesia)
<option value="pfi">PFI</option> </option>
<option value="aji">AJI</option> <option value="ijti">
<option value="lainnya">Lainnya</option> IJTI (Ikatan Jurnalis Televisi Indonesia)
</option>
<option value="pfi">PFI (Pewarta Foto Indonesia)</option>
<option value="aji">
AJI (Asosiasi Jurnalis Indonesia)
</option>
<option value="lainnya">Identitas Lainnya</option>
</select> </select>
{/* Nomor Sertifikasi */} {/* Nomor Sertifikasi */}
@ -792,29 +683,6 @@ export default function SignUp() {
value={certNumber} value={certNumber}
onChange={(e) => setCertNumber(e.target.value)} onChange={(e) => setCertNumber(e.target.value)}
/> />
{/* Password */}
<div className="relative">
<Input
type={isVisible ? "text" : "password"}
required
placeholder="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="pr-10"
/>
<button
type="button"
onClick={toggleVisibility}
className="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-500"
>
{isVisible ? (
<EyeSlashFilledIcon className="h-4 w-4" />
) : (
<EyeFilledIcon className="h-4 w-4" />
)}
</button>
</div>
</div> </div>
)} )}

View File

@ -76,6 +76,7 @@ export default function Navbar() {
const fullname = Cookies.get("ufne"); const fullname = Cookies.get("ufne");
return ( return (
<RevealT>
<header className="relative max-w-[1400px] mx-auto flex items-center justify-between px-4 py-3 border-b bg-white dark:bg-default-50 z-50"> <header className="relative max-w-[1400px] mx-auto flex items-center justify-between px-4 py-3 border-b bg-white dark:bg-default-50 z-50">
<div className="flex flex-row items-center justify-between space-x-4 z-10"> <div className="flex flex-row items-center justify-between space-x-4 z-10">
<Menu <Menu
@ -403,5 +404,6 @@ export default function Navbar() {
</div> </div>
)} )}
</header> </header>
</RevealT>
); );
} }

View File

@ -14,7 +14,7 @@
"target": "es2019", "target": "es2019",
"sourceMap": true, "sourceMap": true,
"allowJs": true, "allowJs": true,
"moduleResolution": "bundler", "moduleResolution": "node",
"skipLibCheck": true "skipLibCheck": true
}, },
"include": [ "include": [