Skip to content

Commit

Permalink
Put notice like button (#104)
Browse files Browse the repository at this point in the history
Co-authored-by: Seokyun Ha <[email protected]>
  • Loading branch information
khkim6040 and BlueHorn07 authored Sep 1, 2024
1 parent 4cbe54c commit 24e2e36
Show file tree
Hide file tree
Showing 3 changed files with 229 additions and 34 deletions.
128 changes: 128 additions & 0 deletions components/notice/notice.card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import React from 'react';
import { PoPoAxios } from '@/lib/axios.instance';
import { INotice } from '@/types/notice.interface';
import { IUser } from '@/types/user.interface';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import { Image, Icon } from 'semantic-ui-react';
import styled from 'styled-components';

interface NoticeCardProps {
notice: INotice;
user: IUser | null;
}

const NoticeCard: React.FC<NoticeCardProps> = ({ notice, user }) => {
const router = useRouter();
const [isLike, setIsLike] = useState<boolean>(false);
const [likeCount, setLikeCount] = useState<number>(0);

useEffect(() => {
const fetchLikeStatus = async () => {
if (!user) return;

const status = await PoPoAxios.get('/noticeLike/status', {
params: { user: user.uuid, notice: notice.id },
withCredentials: true,
});
setIsLike(status.data);
};

const fetchLikeCount = async () => {
const count = await PoPoAxios.get('/noticeLike/count', {
params: { notice: notice.id },
});
setLikeCount(count.data);
};

fetchLikeStatus();
fetchLikeCount();
}, [notice, user]);

const handleLike = async () => {
if (!user) {
alert('로그인이 필요합니다.');
router.push('/auth/login');
return;
}

const data = { user_id: user.uuid, notice_id: notice.id };

if (isLike) {
await PoPoAxios.delete('/noticeLike', {
data,
withCredentials: true,
})
.then(() => setLikeCount(likeCount - 1))
.catch((err) => {
const errMsg = err.response.data.message;
alert(`공지 좋아요 취소에 실패했습니다.\n${errMsg}`);
console.log(data);
console.log(err);
});
} else {
await PoPoAxios.post('/noticeLike', data, { withCredentials: true })
.then(() => setLikeCount(likeCount + 1))
.catch((err) => {
const errMsg = err.response.data.message;
alert(`공지 좋아요에 실패했습니다.\n${errMsg}`);
console.log(data);
console.log(err);
});
}
// toggle my like status
setIsLike(!isLike);
};

return (
<NoticeCardContainer>
<div style={{ fontWeight: 700, fontSize: 18, textDecoration: 'none' }}>
{notice.link ? (
<a
href={notice.link}
target="_blank"
rel="noopener noreferrer"
style={{ color: 'black' }}
>
{notice.title} 🔗
</a>
) : (
notice.title
)}
</div>
<div style={{ marginTop: 8, whiteSpace: 'pre-line', textAlign: 'left' }}>
{notice.content}
</div>
{notice.image_url ? (
<Image src={notice.image_url} alt={notice.title} />
) : null}
<hr />
<div style={{ marginTop: 8, paddingRight: 4, textAlign: 'right' }}>
<button
style={{
background: 'none',
border: 'none',
cursor: 'pointer',
padding: 0,
}}
onClick={handleLike}
>
{isLike ? (
<Icon name="heart" color="red" />
) : (
<Icon name="heart outline" color="grey" />
)}
</button>
<span style={{ marginLeft: 4 }}>{likeCount}</span>
</div>
</NoticeCardContainer>
);
};

export default NoticeCard;

const NoticeCardContainer = styled.div`
background: #eeeeee;
border-radius: 0.4em;
padding: 14px;
`;
51 changes: 17 additions & 34 deletions components/notice/notice.panel.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,29 @@
import { PoPoAxios } from '@/lib/axios.instance';
import { INotice } from '@/types/notice.interface';
import { Image } from 'semantic-ui-react';
import styled from 'styled-components';
import { IUser } from '@/types/user.interface';
import { useEffect, useState } from 'react';
import NoticeCard from './notice.card';

const NoticePanel = ({ noticeList }: { noticeList: INotice[] }) => {
const [user, setUser] = useState<IUser | null>({
name: '',
});

useEffect(() => {
PoPoAxios.get('/auth/verifyToken', {
withCredentials: true,
})
.then((res) => setUser(res.data))
.catch(() => setUser(null));
}, []);

return (
<div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 8 }}>
{noticeList.map((notice) => (
<NoticeCard key={notice.id}>
<div
style={{ fontWeight: 700, fontSize: 18, textDecoration: 'none' }}
>
{notice.link ? (
<a
href={notice.link}
target={'_blank'}
rel={'noopener noreferrer'}
style={{ color: 'black' }}
>
{notice.title} 🔗
</a>
) : (
notice.title
)}
</div>
<div
style={{ marginTop: 8, whiteSpace: 'pre-line', textAlign: 'left' }}
>
{notice.content}
</div>
{notice.image_url ? (
<Image src={notice.image_url} alt={notice.title} />
) : null}
</NoticeCard>
<NoticeCard key={notice.id} notice={notice} user={user} />
))}
</div>
);
};

export default NoticePanel;

const NoticeCard = styled.div`
background: #eeeeee;
border-radius: 0.4em;
padding: 14px;
`;
84 changes: 84 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 24e2e36

Please sign in to comment.