mediahub-fe/app/[locale]/(public)/contact/page.tsx

270 lines
8.8 KiB
TypeScript
Raw Normal View History

2024-12-17 14:27:48 +00:00
"use client";
import { Reveal } from "@/components/landing-page/Reveal";
2025-02-15 14:43:19 +00:00
import { getCookiesDecrypt } from "@/lib/utils";
import React, { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
2025-08-30 02:28:28 +00:00
import { getInfoProfile, getSubjects } from "@/service/auth";
2025-02-15 14:43:19 +00:00
import { close, error, loading, successCallback } from "@/config/swal";
import { sendMessage } from "@/service/landing/landing";
import { useTranslations } from "next-intl";
2025-08-30 02:28:28 +00:00
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useRouter } from "@/i18n/routing";
interface IFormInput {
name: string;
email: string;
phone?: string | undefined;
subjects: string;
othersubject?: string | undefined;
message: string;
}
const ContactForm = () => {
2025-02-15 14:43:19 +00:00
const router = useRouter();
const userId = getCookiesDecrypt("uie");
2025-08-30 02:28:28 +00:00
const [subjects, setSubjects] = useState<any[]>([]);
2025-02-15 14:43:19 +00:00
const [isOtherActive, setIsOtherActive] = useState(false);
const t = useTranslations("LandingPage");
2025-08-30 02:28:28 +00:00
const validationSchema = z.object({
name: z.string().min(1, "Nama tidak boleh kosong"),
email: z.string().email("Email tidak valid"),
phone: z.string().optional(),
subjects: z.string().min(1, "Subjek tidak boleh kosong"),
othersubject: z.string().optional(),
message: z.string().min(1, "Pesan tidak boleh kosong"),
2025-02-15 14:43:19 +00:00
});
2025-08-30 02:28:28 +00:00
type IFormInput = z.infer<typeof validationSchema>;
2025-02-15 14:43:19 +00:00
2025-08-30 02:28:28 +00:00
const {
register,
handleSubmit,
formState: { errors },
setValue,
reset,
} = useForm<IFormInput>({
resolver: zodResolver(validationSchema),
});
2025-02-15 14:43:19 +00:00
2025-08-30 02:28:28 +00:00
// Init state
2025-02-15 14:43:19 +00:00
useEffect(() => {
async function initState() {
const response = await getInfoProfile();
const responseSubject = await getSubjects();
const profile = response?.data?.data;
2025-08-30 02:28:28 +00:00
setSubjects(responseSubject?.data?.data || []);
if (profile) {
setValue("name", profile?.fullname || "");
setValue("email", profile?.email || "");
}
2025-02-15 14:43:19 +00:00
}
initState();
2025-08-30 02:28:28 +00:00
}, [setValue]);
2025-02-15 14:43:19 +00:00
2025-08-30 02:28:28 +00:00
async function save(data: IFormInput) {
2025-02-15 14:43:19 +00:00
loading();
2025-08-30 02:28:28 +00:00
2025-02-15 14:43:19 +00:00
const finalData = {
name: data.name,
email: data.email,
phone: data.phone,
title: isOtherActive ? data.othersubject : data.subjects,
message: data.message,
};
const response = await sendMessage(finalData);
if (response?.error) {
error(response?.message);
2025-08-30 02:28:28 +00:00
return;
2025-02-15 14:43:19 +00:00
}
close();
successCallback("Terima kasih, pesan Anda telah terkirim");
2025-08-30 02:28:28 +00:00
reset();
2025-02-15 14:43:19 +00:00
}
2025-08-30 02:28:28 +00:00
async function onSubmit(data: IFormInput) {
2025-02-15 14:43:19 +00:00
if (userId == undefined) {
2025-08-30 02:28:28 +00:00
router.push("/auth");
2025-02-15 14:43:19 +00:00
} else {
save(data);
}
}
2025-08-30 02:28:28 +00:00
const handleSubjects = (e: React.ChangeEvent<HTMLSelectElement>) => {
if (e.target.value === "Lainnya") {
2025-02-15 14:43:19 +00:00
setIsOtherActive(true);
} else {
setIsOtherActive(false);
}
};
return (
2025-08-30 02:28:28 +00:00
<form
method="POST"
onSubmit={handleSubmit(onSubmit)}
className="max-w-2xl mx-auto bg-white dark:bg-black p-6"
>
2024-12-17 14:27:48 +00:00
<Reveal>
{/* Header */}
<div className="flex items-center justify-center mb-6">
<img src="/assets/icons-contact.png" alt="contact" />
2025-08-30 02:28:28 +00:00
<h2 className="ml-4 text-2xl font-bold">
{t("contactUs", { defaultValue: "Contact Us" })}
</h2>
</div>
2025-08-30 02:28:28 +00:00
<h3 className="text-lg font-semibold text-gray-800 dark:text-white mb-1">
{t("writeMessage", { defaultValue: "Write Message" })}
</h3>
<p className="text-sm text-gray-600 dark:text-white mb-6">
{t("leaveMessage", { defaultValue: "Leave Message" })}
</p>
2024-12-17 14:27:48 +00:00
{/* Form */}
2025-08-30 02:28:28 +00:00
<div>
{/* Name */}
2024-12-17 14:27:48 +00:00
<div className="mb-4">
2025-08-30 02:28:28 +00:00
<label className="block text-sm font-medium text-gray-700 dark:text-white mb-1">
{t("name", { defaultValue: "Name" })}
</label>
<input
type="text"
placeholder={t("enterName", { defaultValue: "Enter Name" })}
className={`w-full p-2 border rounded-md focus:outline-none focus:ring-2 ${
errors.name
? "border-red-500 focus:ring-red-500"
: "border-gray-300 focus:ring-blue-500"
}`}
{...register("name")}
/>
{errors.name && (
<p className="text-red-500 text-sm">{errors.name.message}</p>
)}
2024-12-17 14:27:48 +00:00
</div>
2025-08-30 02:28:28 +00:00
{/* Email */}
2024-12-17 14:27:48 +00:00
<div className="mb-4">
2025-08-30 02:28:28 +00:00
<label className="block text-sm font-medium text-gray-700 dark:text-white mb-1">
Email
</label>
<input
type="email"
placeholder="name@mail.com"
className={`w-full p-2 border rounded-md focus:outline-none focus:ring-2 ${
errors.email
? "border-red-500 focus:ring-red-500"
: "border-gray-300 focus:ring-blue-500"
}`}
{...register("email")}
/>
{errors.email && (
<p className="text-red-500 text-sm">{errors.email.message}</p>
)}
2024-12-17 14:27:48 +00:00
</div>
2025-08-30 02:28:28 +00:00
{/* Phone */}
2024-12-17 14:27:48 +00:00
<div className="mb-4">
2025-08-30 02:28:28 +00:00
<label className="block text-sm font-medium text-gray-700 dark:text-white mb-1">
{t("number", { defaultValue: "Number" })} (Optional)
</label>
<input
type="text"
placeholder={t("enterNumber", { defaultValue: "Enter Number" })}
className="w-full p-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
{...register("phone")}
/>
2024-12-17 14:27:48 +00:00
</div>
2025-08-30 02:28:28 +00:00
{/* Subjects */}
2024-12-17 14:27:48 +00:00
<div className="mb-4">
2025-08-30 02:28:28 +00:00
<label className="block text-sm font-medium text-gray-700 dark:text-white mb-1">
{t("subject", { defaultValue: "Subject" })}
</label>
2025-02-15 14:43:19 +00:00
<select
2025-08-30 02:28:28 +00:00
className={`w-full p-2 border rounded-md focus:outline-none focus:ring-2 ${
errors.subjects
? "border-red-500 focus:ring-red-500"
: "border-gray-300 focus:ring-blue-500"
}`}
2025-02-15 14:43:19 +00:00
{...register("subjects", { onChange: (e) => handleSubjects(e) })}
defaultValue=""
>
2024-12-17 14:27:48 +00:00
<option value="" disabled>
{t("selectSubject", { defaultValue: "Select Subject" })}
2024-12-17 14:27:48 +00:00
</option>
2025-02-15 14:43:19 +00:00
{subjects?.map((list: any) => (
<option key={list.id} value={list.title}>
{list.title}
</option>
))}
2025-08-30 02:28:28 +00:00
<option value="Lainnya">Lainnya</option>
2024-12-17 14:27:48 +00:00
</select>
2025-08-30 02:28:28 +00:00
{errors.subjects && (
<p className="text-red-500 text-sm">{errors.subjects.message}</p>
)}
2024-12-17 14:27:48 +00:00
</div>
2025-08-30 02:28:28 +00:00
{/* Other Subject */}
{isOtherActive && (
<div className="mb-4">
<label className="block text-sm font-medium text-gray-700 dark:text-white mb-1">
Subjek Lainnya
</label>
<input
type="text"
placeholder="Masukkan subjek lainnya"
className={`w-full p-2 border rounded-md focus:outline-none focus:ring-2 ${
errors.othersubject
? "border-red-500 focus:ring-red-500"
: "border-gray-300 focus:ring-blue-500"
}`}
{...register("othersubject")}
/>
{errors.othersubject && (
<p className="text-red-500 text-sm">
{errors.othersubject.message}
</p>
)}
</div>
)}
{/* Message */}
2024-12-17 14:27:48 +00:00
<div className="mb-4">
2025-08-30 02:28:28 +00:00
<label className="block text-sm font-medium text-gray-700 dark:text-white mb-1">
{t("messages", { defaultValue: "Messages" })}
</label>
<textarea
placeholder={t("writeYourMessage", {
defaultValue: "Write Your Message",
})}
rows={4}
className={`w-full p-2 border rounded-md focus:outline-none focus:ring-2 ${
errors.message
? "border-red-500 focus:ring-red-500"
: "border-gray-300 focus:ring-blue-500"
}`}
{...register("message")}
></textarea>
{errors.message && (
<p className="text-red-500 text-sm">{errors.message.message}</p>
)}
2024-12-17 14:27:48 +00:00
</div>
2025-08-30 02:28:28 +00:00
<button
type="submit"
className="w-fit bg-blue-500 flex justify-self-end text-white p-2 px-8 rounded-md hover:bg-blue-600 transition"
>
{t("send", { defaultValue: "Send" })}
2024-12-17 14:27:48 +00:00
</button>
2025-08-30 02:28:28 +00:00
</div>
2024-12-17 14:27:48 +00:00
</Reveal>
2025-02-15 14:43:19 +00:00
</form>
);
};
export default ContactForm;