Skip to content

Commit

Permalink
마을 기사 읽기 페이지 UI작업 (#107)
Browse files Browse the repository at this point in the history
* feat: 기사 페이지 구성
#104

* feat: 기사 밑에 지도 추가 및 헤드라인 설정
#104

* feat: 말풍 추가
#104

* feat: 헤드라인 원복
#104

* feat: KakaoMap 수정
#104

* feat: latitude, longitude
#104

* feat: viewcount 수정
#104

* feat: marker 클릭 가능한지 아닌지 구분
#104

* feat: 기사 클릭하면 이동하도록 설정
#104

* feat: 링크 범위 확장
#104

* feat: 멘트수정
#104

* feat: async 빼기
#104
  • Loading branch information
stopmin authored Jul 21, 2024
1 parent d34a8f3 commit 5d8bbe1
Show file tree
Hide file tree
Showing 9 changed files with 181 additions and 57 deletions.
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 = ({ params }: { params: { id: number } }) => {
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

0 comments on commit 5d8bbe1

Please sign in to comment.