Skip to content

Commit

Permalink
[BYOB-125] Style 및 AppRouter 관련 리팩토링 (#17)
Browse files Browse the repository at this point in the history
* refactor: style 적용 방식 통일

* refactor: AppRouter 구조에 맞게 수정
  • Loading branch information
y-ngm-n authored Jul 24, 2024
1 parent 184f595 commit 2247fe8
Show file tree
Hide file tree
Showing 26 changed files with 129 additions and 206 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
"next": "14.2.4",
"react": "^18",
"react-dom": "^18",
"react-lazy-load-image-component": "^1.6.2",
"react-query": "^3.39.3",
"use-local-storage": "^3.0.0"
},
Expand Down
File renamed without changes.
16 changes: 16 additions & 0 deletions src/app/join/StyledComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use client"

import { Box, styled } from "@mui/material";

export const ContainerBox = styled(Box)({
display: "flex",
flexDirection: "column"
});

export const HeaderBox = styled(Box)({
height: "200px",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
});
14 changes: 14 additions & 0 deletions src/app/join/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from "react";
import { ContainerBox, HeaderBox } from "./StyledComponent";

export default function JoinLayout({ children }: { children: React.ReactNode }) {
return (
<ContainerBox>
<HeaderBox>
<h1>JUMO</h1>
<span>당신이 찾던 완벽한 주류모임, 주모</span>
</HeaderBox>
{children}
</ContainerBox>
);
}
16 changes: 3 additions & 13 deletions src/app/join/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
"use client"

import SelectRegion from "@/component/selectRegion";
import Box from "@mui/material/Box";
import SelectRegion from "@/components/SelectRegion/SelectRegion";
import Button from "@mui/material/Button";
import styles from "../../style/join.module.css";
import { useState } from "react";


Expand All @@ -20,17 +18,9 @@ export default function JoinPage() {
}

return (
<Box className={styles.container}>

<Box className={styles.header}>
<h1>JUMO</h1>
<span>당신이 찾던 완벽한 주류모임, 주모</span>
</Box>

<>
<SelectRegion onChange={regionChange} />

<Button variant="contained" onClick={joinButtonClicked}>회원가입하기</Button>

</Box>
</>
);
}
6 changes: 3 additions & 3 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import "../styles/globals.css";
import Provider from "./provider";
import { GoogleAnalytics } from "@next/third-parties/google"

Expand All @@ -9,8 +9,8 @@ const inter = Inter({ subsets: ["latin"] });
const gaId = process.env.NEXT_PUBLIC_GA_ID;

export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
title: "JUMO",
description: "내가 찾던 완벽한 주류 모임, 주모",
};

export default function RootLayout({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ export const Header = styled(Box)(({ theme }) => ({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
// position: 'fixed',
backgroundColor: 'rgba(255, 255, 255, 1)',
borderBottom: '1px solid #D9D9D9',
boxShadow: theme.shadows[1],
Expand Down
1 change: 0 additions & 1 deletion src/app/meetings/[mId]/StyledComponents.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"use client";

import React from 'react';
import { styled } from '@mui/material/styles';
import { Box, Chip, IconButton, Card } from '@mui/material';

Expand Down
15 changes: 8 additions & 7 deletions src/app/meetings/[mId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
Highlight,
RedText,
} from "./StyledComponents";
import ImageSlider from "../../../component/ImageSlider";
import ImageSlider from "../../../components/ImageSlider/ImageSlider";
import {
Event,
Place,
Expand All @@ -19,7 +19,7 @@ import { formatPrice, formatDate } from "@/utils/format";

const DEFAULT_MESSAGE = <RedText>직접 확인 필요</RedText>;
const EXTERNAL_SERVICE_MESSAGE =
"주모가 아닌 외부 커뮤니티에서 진행하는 주류 모임 입니다. 해당 커뮤티티에서 진행해주세요. (하단에 링크 제공) 해당 커뮤니티 운영 정책에 따라 회원가입 및 추가 절차가 필요할 수 있습니다. 또한 정보가 실제 게시물 정보와 다를 수 있으니 직접 확인해보셔야 합니다.";
"주모가 아닌 외부 커뮤니티에서 진행하는 주류 모임 입니다. 해당 커뮤니티에서 진행해주세요. (하단에 링크 제공) 해당 커뮤니티 운영 정책에 따라 회원가입 및 추가 절차가 필요할 수 있습니다. 또한 정보가 실제 게시물 정보와 다를 수 있으니 직접 확인해보셔야 합니다.";

interface ResponseData {
images: string[];
Expand All @@ -41,6 +41,10 @@ interface ResponseData {
externalLink: string;
}

// type PickedData=Pick<ResponseData,'byob'|'byobMax'>
// type OmittedData=Omit<ResponseData,'byob'|'byobMax'>
// type PartialData=PartialData<ResponseData>

// 데이터를 가져오는 함수
// 1분마다 캐시를 업데이트
async function fetchData(mId: string) {
Expand All @@ -62,12 +66,10 @@ async function fetchData(mId: string) {
}

export default async function PostPage({
params,
params:{mId},
}: {
params: { mId: string };
}) {
const data = await fetchData(params.mId);

const {
images,
name,
Expand All @@ -82,11 +84,10 @@ export default async function PostPage({
paymentMethod,
byob,
byobMin,
byobMax,
description,
externalService,
externalLink,
} = data;
} = await fetchData(mId);

return (
<Container maxWidth="sm" sx={{ padding: 0 }}>
Expand Down
6 changes: 4 additions & 2 deletions src/app/meetings/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
"use client"

import { Typography } from "@mui/material";
import { Header } from "./StyledComponents";
import { Header } from "./StyledComponent";

export default function MeetingsLayout({ children }: { children: React.ReactNode}) {
export default function MeetingsLayout({ children }: { children: React.ReactNode }) {
return (
<div style={{ display: "flex", flexDirection: "column" }}>
<Header style={{ backgroundColor: "white" }}>
Expand Down
48 changes: 28 additions & 20 deletions src/app/meetings/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use client"

import MeetingCard from "@/component/MeetingCard";
import useObserver from "@/hook/useObserver";
import MeetingCard from "@/components/MeetingCard/MeetingCard";
import useObserver from "@/hooks/useObserver";
import { List } from "@mui/material";
import axios from "axios";
import { useEffect, useRef } from "react";
Expand All @@ -24,6 +24,7 @@ export interface Meeting {
thumbnail: string;
externalService: string;
}

interface MeetingResponse {
meetings: Meeting[],
lastId: number,
Expand Down Expand Up @@ -53,11 +54,11 @@ export default function MeetingsPage() {
fetchNextPage,
isFetchingNextPage,
status
} = useInfiniteQuery(
"meetingList",
getMeetingList,
{ getNextPageParam: (lastPage: MeetingResponse) => (lastPage.eof) ? -1 : lastPage.lastId }
);
} = useInfiniteQuery({
queryKey: ["meetingList"],
queryFn: getMeetingList,
getNextPageParam: (lastPage: MeetingResponse) => (lastPage.eof) ? -1 : lastPage.lastId ,
});

// IntersectionObserver API 설정: 페이지 마지막 요소 도달 시 다음 페이지 호출
const target = useRef(null);
Expand All @@ -69,19 +70,26 @@ export default function MeetingsPage() {
return (
<div>
<h4 style={{ textAlign: "center", marginBottom: "0" }}>모임 목록</h4>
{status === "loading" && "불러오는 중..."}
{status === "error" && "에러"}
{status === "success" &&
<List>
{data.pages.map((page: MeetingResponse, i) => (
<div key={i}>
{page.meetings.map((info: Meeting) => (
<MeetingCard key={info.id} meeting={info} />
))}
</div>
))}
</List>
}
{(()=>{
switch(status){
case 'error':
return '에러'
case 'loading':
return "불러오는 중..."
case 'success':
return (<List>
{data.pages.map((page: MeetingResponse, i) => (
<div key={i}>
{page.meetings.map((info: Meeting) => (
<MeetingCard key={info.id} meeting={info} />
))}
</div>
))}
</List>)
default:
return null
}
})()}
<div ref={target} />
{isFetchingNextPage && "이어서 불러오는 중..."}
</div>
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,55 +1,45 @@
"use client";

import { Avatar, ListItem, ListItemAvatar, ListItemText } from "@mui/material";
import { Meeting } from "../app/meetings/page";
import { Avatar, Box, ListItemAvatar, ListItemText } from "@mui/material";
import { Meeting } from "../../app/meetings/page";
import { useRef, useState } from "react";
import useObserver from "@/hook/useObserver";
import Link from "next/link";
import useObserver from "@/hooks/useObserver";
import useLocalStorage from "use-local-storage";
// import { LazyLoadImage } from "react-lazy-load-image-component";
import styles from "../style/meetings.module.css";
import { DescriptionSpan, LinkButton } from "./StyledComponent";

const formatDateTime = (datetime: string) => {
return `${datetime.slice(5, 7)}/${datetime.slice(8, 10)}`;
}


export default function MeetingCard(
{ meeting }: { key: number, meeting: Meeting}
{ meeting }: { meeting: Meeting}
) {
const [visible, setVisible] = useState(false);
const [scrollY, setScrollY] = useLocalStorage("meeting-list-scroll", 0);

// IntersectionObserver API 설정: 뷰포트 안에 요소가 들어올 때만 DOM에 마운트
const target = useRef(null);
const onIntersect = ([entry]: IntersectionObserverEntry[]) => {
return entry.isIntersecting ? setVisible(true) : setVisible(false);
}
const onIntersect = ([entry]: IntersectionObserverEntry[]) => setVisible(entry.isIntersecting);
useObserver({ target, onIntersect, threshold: 0.1 });

return (
<Link
href={`/meetings/${meeting.id}`}
onClick={() => setScrollY(window.scrollY)}
className={styles.container}
>
<ListItem ref={target} className={styles.item}>
<LinkButton ref={target} onClick={() => setScrollY(window.scrollY)} href={`/meetings/${meeting.id}`}>
{visible && (
<>
<Box style={{display:'flex',alignItems:'center',overflow:'hidden',width:'100%'}}>
<ListItemAvatar>
<Avatar alt="thumbnail" src={meeting.thumbnail} />
{/* <LazyLoadImage alt="thumbnail" src={meeting.thumbnail} width="40px" height="auto" /> */}
<Avatar alt="thumbnail" src={meeting.thumbnail} slotProps={{img:{loading: "lazy"}}} />
</ListItemAvatar>
<ListItemText
primary={`${meeting.id}: ${meeting.name}`}
secondary={`${formatDateTime(meeting.meetingAt)} ${meeting.region}`}
primaryTypographyProps={{style:{overflow:'hidden',whiteSpace:'nowrap',textOverflow:'ellipsis'}}}
/>
</>
</Box>
)}
</ListItem>
<span className={styles.description}>
<DescriptionSpan>
{`${meeting.liquors}, 회비 ${meeting.payment}원`}
</span>
</Link>
</DescriptionSpan>
</LinkButton>
)
}
23 changes: 23 additions & 0 deletions src/components/MeetingCard/StyledComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { styled } from "@mui/material";
import emotionStyled from "@emotion/styled";
import Link from "next/link";


export const LinkButton = styled(Link)({
display: 'flex',
flexDirection: 'column',
alignItems: 'flex-start',
margin: '15px 10px',
padding: '5px',
minHeight: "75px",
border: '1px solid',
borderRadius: '5px',
color: 'inherit',
textDecoration:'none',
})

export const DescriptionSpan = emotionStyled.span`
padding: 5px 20px;
white-space: normal;
word-break: break-word;
`
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React, { useEffect, useState } from "react";
import Box from "@mui/material/Box";
import Autocomplete from "@mui/material/Autocomplete";
import TextField from "@mui/material/TextField";
import styles from "../style/selectRegion.module.css";
import { SelectRegionContainer } from "./StyledComponent";

interface Region {
admcd: String;
Expand Down Expand Up @@ -86,8 +86,9 @@ export default function SelectRegion({ onChange }: Props) {
else if (major) onChange(major.admcd);
}, [major, middle, minor, onChange]);


return (
<Box className={styles.container}>
<SelectRegionContainer>
<span>활동 지역을 선택해주세요</span>

<Autocomplete
Expand Down Expand Up @@ -116,6 +117,6 @@ export default function SelectRegion({ onChange }: Props) {
}}
value={minor}
/>
</Box>
</SelectRegionContainer>
);
}
11 changes: 11 additions & 0 deletions src/components/SelectRegion/StyledComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"use client"

import { Box, styled } from "@mui/material";

export const SelectRegionContainer = styled(Box)({
display: "flex",
flexDirection: "column",
justifyContent: "center",
gap: "10px",
padding: "50px 5px",
});
2 changes: 1 addition & 1 deletion src/hook/useObserver.tsx → src/hooks/useObserver.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MutableRefObject, useEffect } from "react";
import { useEffect } from "react";

interface UseObserverProps {
target: any;
Expand Down
Loading

0 comments on commit 2247fe8

Please sign in to comment.