[QUDO-161] fix: portrait image article, fixing user form

This commit is contained in:
Rama Priyanto 2025-06-12 16:16:05 +07:00
parent a1baedde47
commit 34a78b088e
6 changed files with 185 additions and 144 deletions

View File

@ -796,16 +796,16 @@ export default function EditArticleForm(props: { isDetail: boolean }) {
)) ))
) : ( ) : (
<> <>
<div> <div className="w-full h-[480px] flex justify-center items-center">
<Image <Image
alt="main" alt="main"
width={720} width={720}
height={480} height={480}
src={detailfiles[mainImage]?.file_url} src={detailfiles[mainImage]?.file_url}
className="w-[75%] mx-auto" className={`h-[480px] object-cover w-auto`}
/> />
</div> </div>
<div className="flex flex-row gap-2"> <div className="flex flex-row gap-2 mt-2">
{detailfiles?.map((file: any, index: number) => ( {detailfiles?.map((file: any, index: number) => (
<a <a
key={index} key={index}

View File

@ -42,10 +42,10 @@ const masterUserSchema = z.object({
fullname: z.string().min(1, { message: "Required" }), fullname: z.string().min(1, { message: "Required" }),
username: z.string().min(1, { message: "Required" }), username: z.string().min(1, { message: "Required" }),
email: z.string().min(1, { message: "Required" }), email: z.string().min(1, { message: "Required" }),
identityNumber: z.string().min(1, { message: "Required" }), identityNumber: z.string().optional(),
genderType: z.string().min(1, { message: "Required" }), genderType: z.string().optional(),
phoneNumber: z.string().min(1, { message: "Required" }), phoneNumber: z.string().optional(),
address: z.string().min(1, { message: "Required" }), address: z.string().optional(),
userLevelType: userSchema, userLevelType: userSchema,
userRoleType: userSchema, userRoleType: userSchema,
}); });
@ -61,6 +61,7 @@ export default function FormMasterUserEdit() {
const formOptions = { const formOptions = {
resolver: zodResolver(masterUserSchema), resolver: zodResolver(masterUserSchema),
defaultValues: { identityNumber: "" },
}; };
type MicroIssueSchema = z.infer<typeof masterUserSchema>; type MicroIssueSchema = z.infer<typeof masterUserSchema>;
const { const {
@ -139,10 +140,10 @@ export default function FormMasterUserEdit() {
setValue("fullname", profile?.fullname); setValue("fullname", profile?.fullname);
setValue("username", profile?.username); setValue("username", profile?.username);
setValue("email", profile?.email); setValue("email", profile?.email);
setValue("address", profile?.address); setValue("address", profile?.address || "");
setValue("identityNumber", profile?.identityNumber); setValue("identityNumber", profile?.identityNumber || "");
setValue("genderType", profile?.genderType); setValue("genderType", profile?.genderType || "");
setValue("phoneNumber", profile?.phoneNumber); setValue("phoneNumber", profile?.phoneNumber || "");
if (findLevel) { if (findLevel) {
setValue("userLevelType", findLevel); setValue("userLevelType", findLevel);
} }
@ -153,7 +154,12 @@ export default function FormMasterUserEdit() {
}; };
const fetchUserLevel = async () => { const fetchUserLevel = async () => {
const res = await getAllUserLevels(); const request = {
limit: 1000,
page: 1,
};
const res = await getAllUserLevels(request);
if (res?.data?.data) { if (res?.data?.data) {
return setupParent(res?.data?.data, "level"); return setupParent(res?.data?.data, "level");
} }

View File

@ -52,10 +52,10 @@ const masterUserSchema = z.object({
}), }),
passwordValidate: z.string().min(1, { message: "Required" }), passwordValidate: z.string().min(1, { message: "Required" }),
email: z.string().min(1, { message: "Required" }), email: z.string().min(1, { message: "Required" }),
identityNumber: z.string().min(1, { message: "Required" }), identityNumber: z.string().optional(),
genderType: z.string().min(1, { message: "Required" }), genderType: z.string().optional(),
phoneNumber: z.string().min(1, { message: "Required" }), phoneNumber: z.string().optional(),
address: z.string().min(1, { message: "Required" }), address: z.string().optional(),
userLevelType: userSchema, userLevelType: userSchema,
userRoleType: userSchema, userRoleType: userSchema,
}); });
@ -237,7 +237,11 @@ export default function FormMasterUser() {
return ( return (
<div className="mx-5 my-5 overflow-y-auto"> <div className="mx-5 my-5 overflow-y-auto">
<form method="POST" onSubmit={handleSubmit(onSubmit)}> <form
method="POST"
onSubmit={handleSubmit(onSubmit)}
className="w-full lg:w-1/2 lg:ml-4"
>
<Card className="rounded-md p-5 flex flex-col gap-3"> <Card className="rounded-md p-5 flex flex-col gap-3">
<Controller <Controller
control={control} control={control}

View File

@ -69,101 +69,101 @@ export default function Login() {
error("Username & Password Wajib Diisi !"); error("Username & Password Wajib Diisi !");
} else { } else {
// login dengan otp // login dengan otp
// loading(); loading();
// const response: any = await emailValidation(data); const response: any = await emailValidation(data);
// if (response?.error) { if (response?.error) {
// console.log("error", response); console.log("error", response);
// if (response?.message?.messages[0]?.includes("failed to send mail")) { if (response?.message?.messages[0]?.includes("failed to send mail")) {
// error("Gagal Mengirim OTP"); error("Gagal Mengirim OTP");
// return false; return false;
// } }
// if (response?.message?.messages[0]?.includes("username")) { if (response?.message?.messages[0]?.includes("username")) {
// error("Username / Password Tidak Sesuai"); error("Username / Password Tidak Sesuai");
// return false; return false;
// } }
// error("Unknown Error"); error("Unknown Error");
// return false; return false;
// } }
// close(); close();
// if (response?.data?.messages[0] === "Continue to setup email") { if (response?.data?.messages[0] === "Continue to setup email") {
// setFirstLogin(true); setFirstLogin(true);
// } else { } else {
// setNeedOtp(true); setNeedOtp(true);
// } }
// login tanpa otp // login tanpa otp
loading(); // loading();
const response = await postSignIn(data); // const response = await postSignIn(data);
if (response?.error) { // if (response?.error) {
error("Username / Password Tidak Sesuai"); // error("Username / Password Tidak Sesuai");
} else { // } else {
const profile = await getProfile(response?.data?.data?.access_token); // const profile = await getProfile(response?.data?.data?.access_token);
const dateTime: any = new Date(); // const dateTime: any = new Date();
const newTime: any = dateTime.getTime() + 10 * 60 * 1000; // const newTime: any = dateTime.getTime() + 10 * 60 * 1000;
Cookies.set("access_token", response?.data?.data?.access_token, { // Cookies.set("access_token", response?.data?.data?.access_token, {
expires: 1, // expires: 1,
}); // });
Cookies.set("refresh_token", response?.data?.data?.refresh_token, { // Cookies.set("refresh_token", response?.data?.data?.refresh_token, {
expires: 1, // expires: 1,
}); // });
Cookies.set("time_refresh", newTime, { // Cookies.set("time_refresh", newTime, {
expires: 1, // expires: 1,
}); // });
Cookies.set("is_first_login", "true", { // Cookies.set("is_first_login", "true", {
secure: true, // secure: true,
sameSite: "strict", // sameSite: "strict",
}); // });
const resActivity = await saveActivity( // const resActivity = await saveActivity(
{ // {
activityTypeId: 1, // activityTypeId: 1,
url: "https://kontenhumas.com/auth", // url: "https://kontenhumas.com/auth",
userId: profile?.data?.data?.id, // userId: profile?.data?.data?.id,
}, // },
accessData?.id_token // accessData?.id_token
); // );
Cookies.set("profile_picture", profile?.data?.data?.profilePictureUrl, { // Cookies.set("profile_picture", profile?.data?.data?.profilePictureUrl, {
expires: 1, // expires: 1,
}); // });
Cookies.set("uie", profile?.data?.data?.id, { // Cookies.set("uie", profile?.data?.data?.id, {
expires: 1, // expires: 1,
}); // });
Cookies.set("ufne", profile?.data?.data?.fullname, { // Cookies.set("ufne", profile?.data?.data?.fullname, {
expires: 1, // expires: 1,
}); // });
Cookies.set("ulie", profile?.data?.data?.userLevelGroup, { // Cookies.set("ulie", profile?.data?.data?.userLevelGroup, {
expires: 1, // expires: 1,
}); // });
Cookies.set("username", profile?.data?.data?.username, { // Cookies.set("username", profile?.data?.data?.username, {
expires: 1, // expires: 1,
}); // });
Cookies.set("urie", profile?.data?.data?.roleId, { // Cookies.set("urie", profile?.data?.data?.roleId, {
expires: 1, // expires: 1,
}); // });
Cookies.set("roleName", profile?.data?.data?.roleName, { // Cookies.set("roleName", profile?.data?.data?.roleName, {
expires: 1, // expires: 1,
}); // });
Cookies.set("masterPoldaId", profile?.data?.data?.masterPoldaId, { // Cookies.set("masterPoldaId", profile?.data?.data?.masterPoldaId, {
expires: 1, // expires: 1,
}); // });
Cookies.set("ulne", profile?.data?.data?.userLevelId, { // Cookies.set("ulne", profile?.data?.data?.userLevelId, {
expires: 1, // expires: 1,
}); // });
Cookies.set("urce", profile?.data?.data?.roleCode, { // Cookies.set("urce", profile?.data?.data?.roleCode, {
expires: 1, // expires: 1,
}); // });
Cookies.set("email", profile?.data?.data?.email, { // Cookies.set("email", profile?.data?.data?.email, {
expires: 1, // expires: 1,
}); // });
router.push("/admin/dashboard"); // router.push("/admin/dashboard");
Cookies.set("status", "login", { // Cookies.set("status", "login", {
expires: 1, // expires: 1,
}); // });
close(); // close();
} // }
} }
}; };

View File

@ -79,10 +79,22 @@ export default function HeaderNews() {
setHotNews(response?.data?.data); setHotNews(response?.data?.data);
} }
const [portraitMap, setPortraitMap] = useState<any>({});
const handleImageLoad = (e: any, index: number) => {
const { naturalWidth, naturalHeight } = e.target;
const isPortrait = naturalHeight > naturalWidth;
setPortraitMap((prev: any) => ({
...prev,
[index]: isPortrait,
}));
};
return ( return (
<div className="w-full"> <div className="w-full">
<div className="flex flex-col lg:flex-row gap-3 lg:gap-8 bg-white dark:bg-black p-1 lg:p-8 lg:h-[540px] w-full lg:w-[75%] lg:mx-auto"> <div className="flex flex-col lg:flex-row gap-3 lg:gap-8 bg-white dark:bg-black p-1 lg:p-8 lg:h-[540px] w-full lg:w-[75%] lg:mx-auto">
<div className="lg:hidden w-[90%] h-[300px] md:h-[500px] mx-auto"> <div className="lg:hidden w-[90%] h-[200px] md:h-[400px] mx-auto mt-1">
{hotNews?.length > 0 ? ( {hotNews?.length > 0 ? (
<Swiper <Swiper
centeredSlides={true} centeredSlides={true}
@ -111,25 +123,38 @@ export default function HeaderNews() {
}} }}
> >
{hotNews?.map((newsItem: any, index: number) => ( {hotNews?.map((newsItem: any, index: number) => (
<SwiperSlide key={newsItem?.id}> <SwiperSlide
<Card key={newsItem?.id}
radius="lg" className="!w-full h-[200px] md:h-[400px]"
className="border-none rounded-xl shadow-none"
> >
<Card
isFooterBlurred
radius="lg"
className="border-none h-[200px] md:h-[400px] shadow-none dark:bg-stone-800 bg-[#f0f0f0]"
>
<div className="relative w-full h-[200px] md:h-[400px]">
<Image <Image
alt="headernews" alt="headernews"
width={480}
height={480}
onLoad={(e) => handleImageLoad(e, index)}
src={ src={
newsItem?.thumbnailUrl == "" newsItem?.thumbnailUrl === ""
? "/no-image.jpg" ? "/no-image.jpg"
: newsItem?.thumbnailUrl : newsItem?.thumbnailUrl
} }
width={480} className={`!object-cover !rounded-none ${
height={480} portraitMap[index]
className="!w-[90vh] md:!w-[95vh] !h-[200px] md:!h-[400px] object-cover !rounded-b-none" ? "!w-auto object-cover mx-auto"
: "!w-[90vw]"
} !h-[200px] md:!h-[400px]`}
/> />
<CardFooter className="before:bg-white/10 border-gray-100 border-1 rounded-b-xl shadow-sm bottom-1 w-full"> <div className="absolute inset-0 bg-black/20 flex items-center justify-center text-white text-lg font-semibold"></div>
<div className="text-black dark:text-white"> </div>
<CardFooter className="mb-1 max-h-[50px] before:bg-white/10 border-white/20 border-1 overflow-hidden py-1 absolute bottom-0 before:rounded-xl rounded-large w-[calc(100%_-_8px)] shadow-small ml-1 z-10">
<div className="text-white py-1">
<Link <Link
href={`news/detail/${newsItem.id}-${newsItem?.slug}`} href={`news/detail/${newsItem.id}-${newsItem?.slug}`}
> >
@ -141,7 +166,7 @@ export default function HeaderNews() {
{convertDateFormat(newsItem.createdAt)} WIB {convertDateFormat(newsItem.createdAt)} WIB
</p> </p>
<p className="flex items-center gap-1 text-xs"> <p className="flex items-center gap-1 text-xs">
<EyeIcon className="text-black dark:text-white" /> <EyeIcon className="text-white" />
{newsItem.viewCount === null ? 0 : newsItem.viewCount} {newsItem.viewCount === null ? 0 : newsItem.viewCount}
</p> </p>
</div> </div>
@ -152,13 +177,12 @@ export default function HeaderNews() {
</Swiper> </Swiper>
) : ( ) : (
<Skeleton className="rounded-lg"> <Skeleton className="rounded-lg">
<div className="h-[200px] rounded-lg bg-default-300" /> <div className="w-full !h-[500px] rounded-lg bg-default-300" />
</Skeleton> </Skeleton>
)} )}
</div> </div>
<div className="w-[90%] lg:w-[25%] p-2 dark:bg-stone-800 bg-[#f0f0f0] dark:text-white text-black rounded-xl mb-2 md:mb-0 h-[40vh] lg:h-[500px] mx-auto"> <div className="w-[90%] lg:w-[25%] p-2 dark:bg-stone-800 bg-[#f0f0f0] dark:text-white text-black rounded-xl mb-2 md:mb-0 h-[40vh] lg:h-[500px] mx-auto">
<p className="text-base font-bold text-center dark:text-white text-black"> <p className="text-base font-bold text-center dark:text-white text-black">
{/* {t("berita")} */}
Hot Topik Hot Topik
</p> </p>
<ScrollShadow hideScrollBar className="h-[29vh] lg:h-[400px] "> <ScrollShadow hideScrollBar className="h-[29vh] lg:h-[400px] ">
@ -257,20 +281,29 @@ export default function HeaderNews() {
<Card <Card
isFooterBlurred isFooterBlurred
radius="lg" radius="lg"
className="border-none h-[50vh] lg:h-[500px] shadow-none" className="border-none h-[50vh] lg:h-[500px] shadow-none dark:bg-stone-800 bg-[#f0f0f0]"
> >
<div className="relative w-full h-[50vh] lg:h-[500px]">
<Image <Image
alt="headernews" alt="headernews"
width={480} width={480}
height={480} height={480}
onLoad={(e) => handleImageLoad(e, index)}
src={ src={
newsItem?.thumbnailUrl == "" newsItem?.thumbnailUrl === ""
? "/no-image.jpg" ? "/no-image.jpg"
: newsItem?.thumbnailUrl : newsItem?.thumbnailUrl
} }
className="!w-[90vw] !h-[500px] !object-cover !rounded-none" className={`!object-cover !rounded-none ${
portraitMap[index]
? "!w-auto object-cover mx-auto"
: "!w-[90vw]"
} !h-[500px]`}
/> />
<div className="absolute inset-0 bg-black/20 flex items-center justify-center text-white text-lg font-semibold"></div>
</div>
<CardFooter className="mb-1 max-h-[20vh] before:bg-white/10 border-white/20 border-1 overflow-hidden py-1 md:absolute before:rounded-xl rounded-large bottom-1 w-[calc(100%_-_8px)] shadow-small ml-1 z-10"> <CardFooter className="mb-1 max-h-[20vh] before:bg-white/10 border-white/20 border-1 overflow-hidden py-1 md:absolute before:rounded-xl rounded-large bottom-1 w-[calc(100%_-_8px)] shadow-small ml-1 z-10">
<div className="text-white"> <div className="text-white">
<Link <Link
@ -304,8 +337,6 @@ export default function HeaderNews() {
)} )}
</div> </div>
<div className="w-[90%] lg:w-[25%] h-[50vh] lg:h-[500px] rounded-md text-white dark:text-black mx-auto lg:mx-0"> <div className="w-[90%] lg:w-[25%] h-[50vh] lg:h-[500px] rounded-md text-white dark:text-black mx-auto lg:mx-0">
{/* <GPRKominfo /> */}
{selectedTab === "media" ? ( {selectedTab === "media" ? (
<div className="lg:h-[500px] p-2 dark:bg-stone-800 bg-[#f0f0f0] text-black dark:text-white rounded-lg"> <div className="lg:h-[500px] p-2 dark:bg-stone-800 bg-[#f0f0f0] text-black dark:text-white rounded-lg">
<div className="text-sm flex flex-row gap-3 mx-2 mb-2"> <div className="text-sm flex flex-row gap-3 mx-2 mb-2">

View File

@ -167,13 +167,13 @@ export default function DetailNews(props: { data: any; listArticle: any }) {
) : ( ) : (
data?.files?.length > 0 && ( data?.files?.length > 0 && (
<Image <Image
classNames={{ // classNames={{
wrapper: "!w-full !max-w-full", // wrapper: "!w-full !max-w-full",
img: "!w-full", // img: "!w-full",
}} // }}
alt="Main Image" alt="Main Image"
src={data?.files[imageNow]?.file_url} src={data?.files[imageNow]?.file_url}
className="object-cover w-[100%] rounded-md" className="object-cover w-auto h-[360px] md:h-[480px] mx-auto rounded-md"
/> />
) )
)} )}