Compare commits

..

12 Commits

Author SHA1 Message Date
Sabda Yagra 6e3d01cdc0 fix: register form in jouyrnalis
continuous-integration/drone/push Build is passing Details
2026-04-06 12:08:03 +07:00
Sabda Yagra c7eecd40c0 fix: all bugs and error
continuous-integration/drone/push Build is passing Details
2026-04-06 09:31:20 +07:00
Sabda Yagra 65e7c9db41 Merge branch 'dev-1' of http://38.47.180.165:3000/kontenhumas/kontenhumas-fe
continuous-integration/drone/push Build is passing Details
2026-03-31 09:32:08 +07:00
Sabda Yagra 7b364dfbc9 fixing 123
continuous-integration/drone/push Build is passing Details
2026-03-13 14:11:24 +07:00
Sabda Yagra b16f19e859 fix: so many error 2026-03-13 14:06:07 +07:00
Sabda Yagra 9853fc7097 fix: kontenhumas fe
continuous-integration/drone/push Build encountered an error Details
2026-03-12 21:51:27 +07:00
Sabda Yagra 9dc25768a4 fixing
continuous-integration/drone/push Build encountered an error Details
2026-03-11 22:31:25 +07:00
Sabda Yagra 23ff7e5be8 fioxing all
continuous-integration/drone/push Build encountered an error Details
2026-03-09 17:22:14 +07:00
Sabda Yagra ea082c80f6 LALALA
continuous-integration/drone/push Build encountered an error Details
2026-03-09 16:57:20 +07:00
Sabda Yagra 343a0328d4 fix: error push 2026-03-09 15:05:15 +07:00
Sabda Yagra af09a86c48 fixing
continuous-integration/drone/push Build encountered an error Details
2026-03-09 13:33:30 +07:00
Sabda Yagra 421db9c1c3 fixing
continuous-integration/drone/push Build encountered an error Details
2026-03-09 12:50:14 +07:00
6 changed files with 214 additions and 57 deletions

View File

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

View File

@ -88,12 +88,16 @@ export default function SignUp() {
return;
}
// Umum dan Jurnalis → gunakan API createUser
if (role === "umum" || role === "jurnalis") {
if (role === "umum") {
await handleCreateUserUmum(e);
return;
}
if (role === "jurnalis") {
await handleCreateUserJurnalis(e);
return;
}
// Kontributor (sementara ikut umum)
if (role === "kontributor") {
await handleCreateUserKontributor(e);
@ -225,10 +229,10 @@ export default function SignUp() {
MySwal.fire("Peringatan", "Password minimal 8 karakter", "warning");
return;
}
if (!userLevelId || !userRoleId) {
MySwal.fire("Peringatan", "Level dan Role wajib diisi", "warning");
return;
}
// if (!userLevelId || !userRoleId) {
// MySwal.fire("Peringatan", "Level dan Role wajib diisi", "warning");
// return;
// }
// ✅ Generate username otomatis
const autoUsername =
@ -280,6 +284,98 @@ 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 errors: any = {};
@ -592,13 +688,13 @@ export default function SignUp() {
/>
{/* Email */}
<Input
{/* <Input
type="email"
required
placeholder="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
/> */}
{/* Password */}
<div className="relative">
@ -655,6 +751,25 @@ export default function SignUp() {
{/* Jurnalis: Select Keanggotaan */}
{role === "jurnalis" && (
<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
required
className="w-full border border-gray-300 rounded-md p-2 text-sm"
@ -662,17 +777,11 @@ export default function SignUp() {
onChange={(e) => setMembershipType(e.target.value)}
>
<option value="">Pilih jenis keanggotaan</option>
<option value="pwi">
PWI (Persatuan Wartawan Indonesia)
</option>
<option value="ijti">
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>
<option value="pwi">PWI</option>
<option value="ijti">IJTI</option>
<option value="pfi">PFI</option>
<option value="aji">AJI</option>
<option value="lainnya">Lainnya</option>
</select>
{/* Nomor Sertifikasi */}
@ -683,6 +792,29 @@ export default function SignUp() {
value={certNumber}
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>
)}

View File

@ -76,7 +76,6 @@ export default function Navbar() {
const fullname = Cookies.get("ufne");
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">
<div className="flex flex-row items-center justify-between space-x-4 z-10">
<Menu
@ -404,6 +403,5 @@ export default function Navbar() {
</div>
)}
</header>
</RevealT>
);
}

View File

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