clubCreate
'use client'
import Link from 'next/link'
import { useEffect, useState } from 'react'
import api from "@/util/api"
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import DefaultLayout from "@/components/Layouts/DefaultLayout";
import { useRouter } from 'next/navigation';
export default function ClubCreate() {
const router = useRouter();
const [club, setClub] = useState({ clubName: '' });
const handleSubmit = async (e) => {
e.preventDefault();
try {
await api.post('/api/v1/clubs', club);
// 등록 성공 시, 이전 페이지로 이동하거나 사용자에게 알림을 제공할 수 있습니다.
router.push('/club');
} catch (error) {
console.error('등록 중 에러:', error);
}
};
const handleChange = (e) => {
const { name, value } = e.target;
setClub({ ...club, [name]: value });
};
return (
<DefaultLayout>
<h3>동아리 등록</h3>
<form onSubmit={handleSubmit}>
<div>
<label>내용:</label>
<textarea name="clubName" value={club.clubName} onChange={handleChange} />
</div>
<button type="submit">등록</button>
</form>
</DefaultLayout>
);
}
club
'use client'
import Link from 'next/link';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import api from "@/util/api";
import DefaultLayout from "@/components/Layouts/DefaultLayout";
export default function Club() {
const getClubs = async () => {
try {
const response = await api.get('/api/v1/clubs');
return response.data.data.club; // 클럽 목록 가져오기
} catch (error) {
throw new Error('Failed to fetch clubs');
}
};
const { isLoading, error, data } = useQuery({
queryKey: ['clubs'],
queryFn: getClubs
});
const deleteClub = async (id) => {
await api.delete(`/api/v1/clubs/${id}`);
};
const queryClient = useQueryClient();
const mutation = useMutation({
mutationFn: deleteClub,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['clubs'] });
}
});
if (error) {
console.error(error);
}
if (isLoading) {
return <>Loading...</>;
}
if (error) {
console.error(error);
return <>Error occurred: {error.message}</>;
}
if (!data || data.length === 0) {
return <>No data available</>;
}
return (
<DefaultLayout>
<ul>
{data.map((row) => (
<li key={row.id}>
{row.id} /{' '}
<Link href={`/club/${row.id}`}>{row.clubName}</Link> /{' '}
{row.author} / {row.createdDate}
<button onClick={() => mutation.mutate(row.id)}>
삭제
</button>
</li>
))}
</ul>
<Link href="/clubCreate">
Club Create 페이지로 이동
</Link>
</DefaultLayout>
);
}
[id]
'use client'
import { useEffect, useState } from 'react';
import { useParams } from 'next/navigation';
import { useQuery } from '@tanstack/react-query';
import api from "@/util/api";
import DefaultLayout from "@/components/Layouts/DefaultLayout";
import Link from 'next/link'
export default function ClubDetail() {
const params = useParams();
const getClub = async () => {
return await api.get(`/api/v1/clubs/${params.id}`)
.then((response) => response.data.data.club);
}
const { isLoading: clubLoading, error: clubError, data: clubData } = useQuery({
queryKey: ['club', params.id],
queryFn: getClub
});
const getArticles = async () => {
return await api.get(`/api/v1/articles/${params.id}/clubs`)
.then((response) => response.data.data.articles);
}
const { isLoading: articleLoading, error: articleError, data: articleData, refetch } = useQuery({
queryKey: ['articles', params.id],
queryFn: getArticles
});
const [article, setArticle] = useState({ subject: '', content: ''});
const handleSubmit = async (e) => {
e.preventDefault();
await api
.post('/api/v1/articles', { ...article, club: { id: params.id } })
.then((response) => {
console.log(response);
setArticle({ subject: '', content: '' });
refetch(); // 새로운 답변 작성 후 답변 리스트를 다시 불러옴
})
.catch((error) => {
console.log(error);
});
};
const handleChange = (e) => {
const { name, value } = e.target;
setArticle({ ...article, [name]: value });
};
if (articleError || clubLoading) {
console.log(articleError || clubLoading);
}
if (articleLoading || clubLoading) {
return <>Loading...</>;
}
return (
<DefaultLayout>
{clubData && (
<>
<h1>동아리 상세 {params.id}번</h1>
<div>{clubData.clubName}</div>
<Link href={`/article/${params.id}/edit`}>수정하기</Link>
</>
)}
<h3>게시글 작성</h3>
<form onSubmit={handleSubmit}>
<div>
<label>제목:</label>
<input type="text" name="subject" value={article.subject} onChange={handleChange} />
</div>
<div>
<label>내용:</label>
<textarea name="content" value={article.content} onChange={handleChange} />
</div>
<button type="submit">등록</button>
</form>
<h3>게시글 목록</h3>
{articleData && articleData.length > 0 ? (
articleData.map((article, index) => (
<div key={index}>
<Link href={`/club/${article.id}/detail`}>{article.subject}</Link>
<div>{article.content}</div>
</div>
))
) : (
<div>답글이 없습니다.</div>
)}
</DefaultLayout>
);
}
detail
'use client'
import { useEffect, useState } from 'react';
import { useParams } from 'next/navigation';
import { useQuery } from '@tanstack/react-query';
import api from "@/util/api";
import DefaultLayout from "@/components/Layouts/DefaultLayout";
import Link from 'next/link'
export default function ArticleDetail() {
const params = useParams();
const getArticle = async () => {
return await api.get(`/api/v1/articles/${params.id}`)
.then((response) => response.data.data.article);
}
const { isLoading: articleLoading, error: articleError, data: articleData } = useQuery({
queryKey: ['article', params.id],
queryFn: getArticle
});
const getAnswers = async () => {
return await api.get(`/api/v1/answers/${params.id}/articles`)
.then((response) => response.data.data.answers);
}
const { isLoading: answerLoading, error: answerError, data: answerData, refetch } = useQuery({
queryKey: ['answers', params.id],
queryFn: getAnswers
});
const [answer, setAnswer] = useState({ content: '' });
const handleSubmit = async (e) => {
e.preventDefault();
await api
.post('/api/v1/answers', { ...answer, article: { id: params.id } })
.then((response) => {
console.log(response);
setAnswer({ content: '' });
refetch(); // 새로운 답변 작성 후 답변 리스트를 다시 불러옴
})
.catch((error) => {
console.log(error);
});
};
const handleChange = (e) => {
const { name, value } = e.target;
setAnswer({ ...answer, [name]: value });
};
if (articleError || answerError) {
console.log(articleError || answerError);
}
if (articleLoading || answerLoading) {
return <>Loading...</>;
}
return (
<DefaultLayout>
{articleData && (
<>
<h1>게시판 상세 {params.id}번</h1>
<div>{articleData.subject}</div>
<div>{articleData.content}</div>
<Link href={`/article/${params.id}/edit`}>수정하기</Link>
</>
)}
<h3>답글 작성</h3>
<form onSubmit={handleSubmit}>
<div>
<label>내용:</label>
<textarea name="content" value={answer.content} onChange={handleChange} />
</div>
<button type="submit">등록</button>
</form>
<h3>답글 목록</h3>
{answerData && answerData.length > 0 ? (
answerData.map((answer, index) => (
<div key={index}>
<div>{answer.content}</div>
</div>
))
) : (
<div>답글이 없습니다.</div>
)}
</DefaultLayout>
);
}