Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

마을 기사 읽기 페이지 UI작업 #107

Merged
merged 13 commits into from
Jul 21, 2024
8 changes: 7 additions & 1 deletion src/app/insight/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,13 @@ const Page = () => {
sx={{ cursor: 'pointer' }}
onClick={() => handleInsightClick(insight)}
>
<NewsCardVertical date={insight.date} description={insight.content} title={insight.title} />
<NewsCardVertical
date={insight.date}
description={insight.content}
id={insight.id}
path="insight"
title={insight.title}
/>
</Box>
</Grid>
))}
Expand Down
2 changes: 2 additions & 0 deletions src/app/newsletter/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const Page = () => {
content={item.content}
id={item.id}
imageUrl={item.imageUrl}
path="newsletter"
publishedAt={item.publishedAt.split('T')[0]}
title={item.title}
/>
Expand All @@ -70,6 +71,7 @@ const Page = () => {
content={filteredItem.content}
id={filteredItem.id}
imageUrl={filteredItem.imageUrl}
path="newsletter"
publishedAt={filteredItem.publishedAt.split('T')[0]}
title={filteredItem.title}
/>
Expand Down
69 changes: 69 additions & 0 deletions src/app/village/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
'use client';

import Image from 'next/image';

import { Box, Card, CardContent, Stack, Typography } from '@mui/material';

import CommentCard from '@/components/CommentCard';
import GradientBox from '@/components/GradientBox';
import Headline from '@/components/Headline';
import KakaoMap from '@/components/KakaoMap';
import color from '@/constants/color';
import hiddenGems from '@/mocks/villages';

const Page = async ({ params }: { params: { id: number } }) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Client components cannot be async functions. 라고 합니다!!
async 빼주세요~!

const village = hiddenGems[params.id - 1];

return (
<GradientBox>
<Stack alignItems="center" p={10}>
<Box sx={{ maxWidth: '600px' }}>
<Box sx={{ marginBottom: '2rem' }}>
<Headline
source="경단"
title={village.title}
uploadDate={village.publishedAt}
viewCount={village.viewCount}
/>
</Box>
<CommentCard isCharacter isStroke content={`오늘은 ${village.title}에 대해 소개해줄게😃`} />
<Box mt="2.5rem">
<Box>
{village.imageUrl && (
<Image
priority
alt="articleImage"
height={400}
src={village.imageUrl}
style={{ objectFit: 'contain' }}
width={600}
/>
)}
</Box>
<Card sx={{ marginTop: '2rem', backgroundColor: 'transparent', boxShadow: 'none' }}>
<CardContent sx={{ padding: 0 }}>
<Typography fontSize="16px" py={2} variant="body2" whiteSpace="pre-line">
{village.content}
</Typography>
</CardContent>
</Card>
</Box>
<Typography color={color.blue} fontSize="20px" py={2} variant="h3" />
<CommentCard isCharacter isChat content={`${village.title} 위치는 여기야`} />
<CommentCard isChat content="다음에 같이 가보자!" />
</Box>
<Box style={{ alignItems: 'center' }} width={600}>
<KakaoMap
initialLat={village.latitude}
initialLon={village.longitude}
isMarkerClicked={false}
level={7}
villages={[village]}
/>
</Box>
</Stack>
</GradientBox>
);
};

export default Page;
5 changes: 4 additions & 1 deletion src/app/village/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ const Page = () => {
<NewsCardVertical
date={village.publishedAt}
description={village.content}
id={village.id}
imageUrl={village.imageUrl}
path="village"
title={village.title}
/>
</Box>
Expand All @@ -49,7 +51,7 @@ const Page = () => {
<Typography gutterBottom color={color.blue} component="h1" variant="h4">
지도에서 보는 마을
</Typography>
<KakaoMap villages={villages} />
<KakaoMap isMarkerClicked initialLat={36.5} initialLon={127.5} level={13} villages={villages} />
</Box>
<Box>
{villages.slice(3).map((filteredItem) => (
Expand All @@ -58,6 +60,7 @@ const Page = () => {
content={filteredItem.content}
id={filteredItem.id}
imageUrl={filteredItem.imageUrl}
path="village"
publishedAt="2024-01-20"
title={filteredItem.title}
/>
Expand Down
31 changes: 22 additions & 9 deletions src/components/KakaoMap.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client';

import React, { useEffect } from 'react';

declare global {
Expand All @@ -11,30 +13,35 @@ interface Village {
title: string;
content: string;
imageUrl: string;
x: number;
y: number;
latitude: number;
longitude: number;
}

interface KakaoMapProps {
initialLat: number;
initialLon: number;
level: number;
villages: Village[];
isMarkerClicked?: boolean;
}

const KakaoMap = ({ villages }: KakaoMapProps) => {
const KakaoMap = ({ villages, initialLat, initialLon, level, isMarkerClicked = false }: KakaoMapProps) => {
useEffect(() => {
const initializeMap = () => {
const container = document.getElementById('map');
if (!container) {
console.error('Map container not found');
return;
}

const options = {
center: new window.kakao.maps.LatLng(36.5, 127.5),
level: 13,
center: new window.kakao.maps.LatLng(initialLat, initialLon),
level,
};
const map = new window.kakao.maps.Map(container, options);

villages.forEach((village) => {
const markerPosition = new window.kakao.maps.LatLng(village.x, village.y);
const markerPosition = new window.kakao.maps.LatLng(village.latitude, village.longitude);
const marker = new window.kakao.maps.Marker({
position: markerPosition,
});
Expand All @@ -53,7 +60,9 @@ const KakaoMap = ({ villages }: KakaoMapProps) => {
});

window.kakao.maps.event.addListener(marker, 'click', () => {
window.location.href = `/village/${village.id}`;
if (isMarkerClicked) {
window.location.href = `/village/${village.id}`;
}
});
});
};
Expand All @@ -72,15 +81,19 @@ const KakaoMap = ({ villages }: KakaoMapProps) => {
window.kakao.maps.load(() => {
initializeMap();
});
} else {
console.error('Kakao maps load function is not available');
}
};
script.onerror = () => {};
script.onerror = () => {
console.error('Failed to load Kakao Maps script');
};

document.head.appendChild(script);
};

loadKakaoMap();
}, [villages]);
}, [villages, initialLat, initialLon, level, isMarkerClicked]);

return (
<div
Expand Down
5 changes: 3 additions & 2 deletions src/components/NewsCardHorizontal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@ interface NewsCardHorizontalProps {
content: string;
publishedAt: string;
imageUrl?: string;
path: string;
}

const NewsCardHorizontal = ({ id, title, content, publishedAt, imageUrl }: NewsCardHorizontalProps) => {
const NewsCardHorizontal = ({ id, title, content, publishedAt, imageUrl, path }: NewsCardHorizontalProps) => {
return (
<Stack alignItems="center" direction="row" height="180px" justifyContent="space-between">
<Stack>
<Typography color={color.blue} fontWeight="600" mb={1} variant="body2">
{publishedAt}
</Typography>
<Link color="inherit" href={`/newsletter/${id}`} underline="none">
<Link color="inherit" href={`/${path}/${id}`} underline="none">
<Typography
mb={1}
sx={{
Expand Down
84 changes: 53 additions & 31 deletions src/components/NewsCardVertical.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,70 @@
import { Card, CardContent, CardMedia, Typography } from '@mui/material';
import Image from 'next/image';

import { Card, CardContent, CardMedia, Link, Typography } from '@mui/material';

import color from '@/constants/color';

interface NewsCardVerticalProps {
id: number;
date: string;
title: string;
description: string;
imageUrl?: string;
path?: string;
}

const NewsCardVertical = ({ date, title, description, imageUrl }: NewsCardVerticalProps) => {
const NewsCardVertical = ({ id, date, title, description, imageUrl, path }: NewsCardVerticalProps) => {
return (
<Card sx={{ maxWidth: 350, boxShadow: 'none', borderRadius: 4 }}>
{imageUrl && (
<CardMedia alt="articleImage" component="img" image={imageUrl} sx={{ height: 190, borderRadius: 2 }} />
)}
<Link color="inherit" href={`/${path}/${id}`} underline="none">
{imageUrl && (
<CardMedia alt="articleImage" component="img" image={imageUrl} sx={{ height: 190, borderRadius: 2 }} />
)}
</Link>
<CardContent>
<Typography color={color.blue} fontWeight="600" mb={1} variant="body2">
{date}
</Typography>
<Typography
mb={1}
sx={{
overflow: 'hidden',
WebkitLineClamp: 2,
WebkitBoxOrient: 'vertical',
display: '-webkit-box',
}}
variant="h5"
>
{title}
</Typography>
<Typography
sx={{
overflow: 'hidden',
WebkitLineClamp: 3,
WebkitBoxOrient: 'vertical',
display: '-webkit-box',
}}
variant="body2"
>
{description}
</Typography>
<Link color="inherit" href={`/${path}/${id}`} underline="none">
<Typography color={color.blue} fontWeight="600" mb={1} variant="body2">
{date}
</Typography>
<Typography
mb={1}
sx={{
overflow: 'hidden',
WebkitLineClamp: 2,
WebkitBoxOrient: 'vertical',
display: '-webkit-box',
}}
variant="h5"
>
{title}
</Typography>
<Typography
sx={{
overflow: 'hidden',
WebkitLineClamp: 3,
WebkitBoxOrient: 'vertical',
display: '-webkit-box',
}}
variant="body2"
>
{description}
</Typography>
</Link>
</CardContent>
{imageUrl && (
<Link
borderRadius={2}
height={130}
href={`/${path}/${id}`}
minWidth={230}
ml={3}
mt={2}
overflow="hidden"
position="relative"
>
<Image fill priority alt="articleImage" sizes="100%" src={imageUrl} style={{ objectFit: 'cover' }} />
</Link>
)}
</Card>
);
};
Expand Down
Loading