feat: Implement blog API service and refactor components for improved data fetching

This commit is contained in:
Wini_Fy
2026-02-04 15:33:02 +07:00
parent d46c420aaf
commit 9a71d39ebf
16 changed files with 790 additions and 149 deletions

View File

@@ -21,6 +21,10 @@ export default function CommentForm({
const router = useRouter();
const [isPending, setIsPending] = useState(false);
const [authorName, setAuthorName] = useState("");
const [authorEmail, setAuthorEmail] = useState("");
const [authorPhone, setAuthorPhone] = useState("");
const [authorAddress, setAuthorAddress] = useState("");
const [authorDate, setAuthorDate] = useState("");
const [content, setContent] = useState(initialContent);
const [error, setError] = useState<string | null>(null);
const [success, setSuccess] = useState<string | null>(null);
@@ -37,6 +41,12 @@ export default function CommentForm({
return;
}
// Basic email validation if provided
if (authorEmail.trim() && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(authorEmail.trim())) {
setError("Please enter a valid email address.");
return;
}
try {
setIsPending(true);
const res = await fetch(`${apiUrl}/api/blog/${slug}/comments`, {
@@ -47,6 +57,10 @@ export default function CommentForm({
},
body: JSON.stringify({
authorName: authorName.trim(),
...(authorEmail.trim() ? { authorEmail: authorEmail.trim() } : {}),
...(authorPhone.trim() ? { authorPhone: authorPhone.trim() } : {}),
...(authorAddress.trim() ? { authorAddress: authorAddress.trim() } : {}),
...(authorDate.trim() ? { authorDate: authorDate.trim() } : {}),
content: content.trim(),
...(parentId ? { parentId } : {}),
}),
@@ -58,6 +72,10 @@ export default function CommentForm({
}
setAuthorName("");
setAuthorEmail("");
setAuthorPhone("");
setAuthorAddress("");
setAuthorDate("");
setContent("");
setSuccess("Comment submitted.");
@@ -83,7 +101,7 @@ export default function CommentForm({
<form onSubmit={onSubmit} className="contact-form-items">
<div className="row g-4">
<div className="col-lg-6">
<div className="col-lg-4">
<div className="form-clt">
<span>Your Name</span>
<input
@@ -93,6 +111,63 @@ export default function CommentForm({
value={authorName}
onChange={(e) => setAuthorName(e.target.value)}
disabled={isPending}
required
/>
</div>
</div>
<div className="col-lg-4">
<div className="form-clt">
<span>Your Email</span>
<input
type="email"
name="authorEmail"
placeholder="Your email"
value={authorEmail}
onChange={(e) => setAuthorEmail(e.target.value)}
disabled={isPending}
/>
</div>
</div>
<div className="col-lg-4">
<div className="form-clt">
<span>Your Phone</span>
<input
type="text"
name="authorPhone"
placeholder="Phone Number"
value={authorPhone}
onChange={(e) => setAuthorPhone(e.target.value)}
disabled={isPending}
/>
</div>
</div>
<div className="col-lg-6">
<div className="form-clt">
<span>Your Address</span>
<input
type="text"
name="authorAddress"
placeholder="Address Now"
value={authorAddress}
onChange={(e) => setAuthorAddress(e.target.value)}
disabled={isPending}
/>
</div>
</div>
<div className="col-lg-6">
<div className="form-clt">
<span>Your Date</span>
<input
type="text"
name="authorDate"
placeholder="Date"
value={authorDate}
onChange={(e) => setAuthorDate(e.target.value)}
disabled={isPending}
/>
</div>
</div>
@@ -105,6 +180,7 @@ export default function CommentForm({
value={content}
onChange={(e) => setContent(e.target.value)}
disabled={isPending}
required
></textarea>
</div>
</div>