first commit
This commit is contained in:
85
laravel/resources/js/pages/Articles/Show.tsx
Normal file
85
laravel/resources/js/pages/Articles/Show.tsx
Normal file
@@ -0,0 +1,85 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import type { Article, Comment } from '@/types/article';
|
||||
|
||||
export default function Show({ articleId }: { articleId: number }) {
|
||||
const [article, setArticle] = useState<Article | null>(null);
|
||||
const [form, setForm] = useState({ author_name: '', content: '' });
|
||||
|
||||
// загрузка статьи
|
||||
useEffect(() => {
|
||||
fetch(`/api/articles/${articleId}`)
|
||||
.then((res) => res.json())
|
||||
.then((res) => setArticle(res.data)) // <-- берём data
|
||||
.catch(console.error);
|
||||
}, [articleId]);
|
||||
|
||||
const submit = async () => {
|
||||
if (!form.author_name || !form.content) return;
|
||||
|
||||
const res = await fetch(`/api/articles/${articleId}/comments`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(form),
|
||||
});
|
||||
|
||||
if (!res.ok) return;
|
||||
|
||||
const result = await res.json();
|
||||
const newComment: Comment = result.data; // <-- API возвращает CommentResource
|
||||
|
||||
setArticle((prev) =>
|
||||
prev ? { ...prev, comments: [...prev.comments, newComment] } : prev,
|
||||
);
|
||||
|
||||
setForm({ author_name: '', content: '' });
|
||||
};
|
||||
|
||||
if (!article) return <div className="p-6">Статья не найдена</div>;
|
||||
|
||||
return (
|
||||
<div className="space-y-6 p-6">
|
||||
<h1 className="text-2xl font-bold">{article.title}</h1>
|
||||
<p className="whitespace-pre-line text-gray-700">
|
||||
{article.content}
|
||||
</p>
|
||||
|
||||
<section className="space-y-3">
|
||||
<h2 className="text-xl font-semibold">Комментарии</h2>
|
||||
{article.comments.map((c) => (
|
||||
<div key={c.id} className="rounded border p-3">
|
||||
<div className="text-sm text-gray-500">
|
||||
{c.author_name}
|
||||
</div>
|
||||
<div>{c.content}</div>
|
||||
</div>
|
||||
))}
|
||||
</section>
|
||||
|
||||
<section className="space-y-2">
|
||||
<h3 className="font-semibold">Добавить комментарий</h3>
|
||||
<input
|
||||
className="w-full border p-2"
|
||||
placeholder="Ваше имя"
|
||||
value={form.author_name}
|
||||
onChange={(e) =>
|
||||
setForm({ ...form, author_name: e.target.value })
|
||||
}
|
||||
/>
|
||||
<textarea
|
||||
className="w-full border p-2"
|
||||
placeholder="Комментарий"
|
||||
value={form.content}
|
||||
onChange={(e) =>
|
||||
setForm({ ...form, content: e.target.value })
|
||||
}
|
||||
/>
|
||||
<button
|
||||
onClick={submit}
|
||||
className="rounded bg-black px-4 py-2 text-white"
|
||||
>
|
||||
Отправить
|
||||
</button>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user