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

feature/#31 스프린트 2-1 병합 #40

Merged
merged 2 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 14 additions & 17 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,41 @@
import MoimInput from './components/Input/MoimInput';
import { Input_Info_List } from './constants';
import { Global } from '@emotion/react';
import Button from './components/Button/Button';
import reset from './reset';
import MoimCardList from './components/MoimCardList/MoimCardList';

import Plus from './common/assets/tabler_plus.svg';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import {
QueryClient,
QueryClientProvider,
MutationCache,
} from '@tanstack/react-query';
import { RouterProvider, createBrowserRouter } from 'react-router-dom';

import ENDPOINTS from './constants/endpoints';
import TmpAddMoim from './pages/TmpAddMoim';
import TmpMain from './pages/TmpMain';
import { useMemo } from 'react';
import MoimListPage from './pages/MoimList';
import MoimRegisterPage from './pages/MoimRegister';

const router = createBrowserRouter([
{
path: ENDPOINTS.main,
element: <TmpMain />,
element: <MoimListPage />,
},
{
path: ENDPOINTS.addMoim,
element: <TmpAddMoim />,
element: <MoimRegisterPage />,
},
]);

export default function App() {
const queryClient = useMemo(() => {
return new QueryClient();
return new QueryClient({
mutationCache: new MutationCache({
onError: (e: Error) => console.log(e),
}),
});
}, []);

return (
<>
<Global styles={reset} />
<MoimInput data={Input_Info_List['title']} />
<MoimCardList data={mockdata} />
<Button shape="circle">
<img src={Plus}></img>
</Button>
<Button shape="bar">등록하기</Button>
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
</QueryClientProvider>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/apis/env.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const ENV = {
baseUrl: 'https://mouda.com',
baseUrl: 'http://43.202.67.25',
};

export default ENV;
5 changes: 4 additions & 1 deletion frontend/src/apis/gets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import ENV from './env';
export const getMoims = async (): Promise<MoimInfo[]> => {
const url = `${ENV.baseUrl}/${'v1/moim'}`;

const headers = new Headers();
headers.append('Content-Type', 'application/json');

const options = {
method: 'GET',
headers: {
Expand All @@ -18,5 +21,5 @@ export const getMoims = async (): Promise<MoimInfo[]> => {
if (statusHead === 4 || statusHead === 5)
throw new Error('모임을 받아오지 못했습니다.');
const json = (await response.json()) as GetMoim;
return json.data;
return json.data.moims;
};
2 changes: 1 addition & 1 deletion frontend/src/apis/posts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ export const postMoim = async (moim: MoimInfo): Promise<number> => {
method: 'POST',
headers: {
'Content-Type': 'application/json',
body: JSON.stringify(moim),
},
body: JSON.stringify(moim),
};

const response = await fetch(url, options);
Expand Down
8 changes: 6 additions & 2 deletions frontend/src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import type ButtonProps from './Button.type';
import { shapes } from './Button.style';

export default function Button(props: ButtonProps) {
const { shape, children } = props;
return <button css={shapes[shape]}>{children}</button>;
const { shape, onClick, children } = props;
return (
<button css={shapes[shape]} onClick={onClick}>
{children}
</button>
);
}
1 change: 1 addition & 0 deletions frontend/src/components/Button/Button.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ import { ReactNode } from 'react';

export default interface ButtonProps {
shape: 'circle' | 'bar';
onClick: () => void;
children: ReactNode;
}
2 changes: 1 addition & 1 deletion frontend/src/components/Card/MoimCard.type.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MoimInfo } from '../../type';
import { MoimInfo } from '../../types/requests';

export default interface MoimCardProps {
data: MoimInfo;
Expand Down
9 changes: 8 additions & 1 deletion frontend/src/components/Input/MoimInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import MoimInputProps from './MoimInput.type';
import * as S from './MoimInput.style';

export default function MoimInput(props: MoimInputProps) {
const { title, type, placeholder, required } = props.data;
const {
name,
data: { title, type, placeholder, required },
onChange,
} = props;

return (
<label htmlFor={title}>
<h3 css={S.title}>
Expand All @@ -11,10 +16,12 @@ export default function MoimInput(props: MoimInputProps) {
</h3>

<input
name={name}
css={S.input}
type={type}
placeholder={placeholder}
id={title}
onChange={onChange}
></input>
</label>
);
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/components/Input/MoimInput.type.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { ChangeEvent } from 'react';
import { InputInfoType } from '../../constants';

export default interface MoimInputProps {
name: string;
data: InputInfoType;
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
}
2 changes: 1 addition & 1 deletion frontend/src/components/MoimCardList/MoimCardList.type.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MoimInfo } from '../../type';
import { MoimInfo } from '../../types/requests';

export default interface MoimCardListProps {
data: MoimInfo[];
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const Input_Info_List: Record<string, InputInfoType> = {
},
maxPeople: {
title: '최대인원수',
type: 'text',
type: 'number',
placeholder: '0명',
required: true,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { css } from '@emotion/react';

export const bottomFixedStyle = css`
// TODO: 바텀 버튼 UI에 대한 기획 논의 필요
position: fixed;
bottom: 26px;
padding: 0 16px;

width: calc(100% - 32px); // 전체 너비에서 양쪽 패딩(16px * 2)을 뺀 값
width: 100%;
`;
13 changes: 9 additions & 4 deletions frontend/src/layouts/FormLayout/FormHeader/FormHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { PropsWithChildren } from 'react';
import { ReactNode } from 'react';
import BackArrowLogo from './BackArrowLogo';
import * as S from './FormHeader.style';

export default function FormHeader(props: PropsWithChildren) {
const { children } = props;
interface FormHeaderProps {
onBackArrowClick: () => void;
children: ReactNode;
}

export default function FormHeader(props: FormHeaderProps) {
const { children, onBackArrowClick } = props;

return (
// TODO: '모임등록하기'가 정가운데에 오지 않음
<header css={S.headerStyle}>
<span>
<span onClick={onBackArrowClick}>
<BackArrowLogo />
</span>
<span css={S.headerTitleStyle}>{children}</span>
Expand Down
1 change: 1 addition & 0 deletions frontend/src/layouts/FormLayout/FormLayout.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export const containerStyle = css`
display: flex;
flex-direction: column;
gap: 10px;
margin-bottom: 100px;
`;
3 changes: 1 addition & 2 deletions frontend/src/layouts/FormLayout/FormMain/FormMain.style.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { css } from '@emotion/react';

export const formStyle = css`
padding: 0px 22px;
padding: 16px 22px;
display: flex;
flex-direction: column;
gap: 12px;
padding: 16px 0;
`;
16 changes: 9 additions & 7 deletions frontend/src/layouts/HomeLayout.tsx/HomeMain/HomeMain.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ export const navStyle = css`
gap: 12px;
`;

export const navItemStyle = css`
color: rgba(71, 123, 255, 1);
font-weight: 600;
font-size: 18px;
line-height: 22.88px;
border-bottom: solid 2px;
`;
export const navItemStyle = (isTurnedOn: boolean) => {
return css`
color: ${isTurnedOn ? 'rgba(71, 123, 255, 1)' : '#ededed'};
font-weight: 600;
font-size: 18px;
line-height: 22.88px;
border-bottom: solid 2px;
`;
};
7 changes: 4 additions & 3 deletions frontend/src/layouts/HomeLayout.tsx/HomeMain/HomeMain.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { PropsWithChildren } from 'react';
import * as S from './HomeMain.style';

import { PropsWithChildren } from 'react';

export default function HomeMain(props: PropsWithChildren) {
const { children } = props;
return (
<main css={S.mainStyle}>
<nav css={S.navStyle}>
<p css={S.navItemStyle}>모임목록</p>
<p css={S.navItemStyle}> 나의모임</p>
<p css={S.navItemStyle(true)}>모임목록</p>
<p css={S.navItemStyle(false)}> 나의모임</p>
</nav>

{children}
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/mutaions/useAddMoim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
import QUERY_KEYS from '../queryKeys';
import { postMoim } from '../apis/posts';

export default function useAddToCart() {
export default function useAddMoim(onSuccess: () => void) {
const queryClient = useQueryClient();

return useMutation({
mutationFn: postMoim,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.moims] });
onSuccess();
},
});
}
14 changes: 11 additions & 3 deletions frontend/src/pages/MoimList.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
import HomeLayout from '../layouts/HomeLayout.tsx/HomeLayout';
import { meetings } from '../layouts/HomeLayout.tsx/mockData';
import MoimCardList from '../components/MoimCardList/MoimCardList';
import Button from '../components/Button/Button';
import Plus from '../common/assets/tabler_plus.svg';
import { useNavigate } from 'react-router-dom';
import ENDPOINTS from '../constants/endpoints';
import useMoims from '../queries/useMoims';

export default function MoimListPage() {
const navigate = useNavigate();
const { moims } = useMoims();
return (
<HomeLayout>
<HomeLayout.Header>우아한테크코스</HomeLayout.Header>
<HomeLayout.Main>
<MoimCardList data={meetings} />
{moims && <MoimCardList data={moims} />}
</HomeLayout.Main>

<HomeLayout.HomeFixedButtonWrapper>
<Button shape="circle">+</Button>
<Button shape="circle" onClick={() => navigate(ENDPOINTS.addMoim)}>
<img src={Plus} />
</Button>
</HomeLayout.HomeFixedButtonWrapper>
</HomeLayout>
);
Expand Down
50 changes: 47 additions & 3 deletions frontend/src/pages/MoimRegister.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,65 @@
import { useNavigate } from 'react-router-dom';
import Button from '../components/Button/Button';
import MoimInput from '../components/Input/MoimInput';
import { Input_Info_List } from '../constants';
import FormLayout from '../layouts/FormLayout/FormLayout';
import ENDPOINTS from '../constants/endpoints';
import { ChangeEvent, useState } from 'react';
import { MoimInfo } from '../types/requests';
import useAddMoim from '../mutaions/useAddMoim';

export default function MoimRegisterPage() {
const navigate = useNavigate();
const { mutate } = useAddMoim(() => navigate(ENDPOINTS.main));

const [inputData, setInputData] = useState<MoimInfo>({
title: '',
date: '',
time: '',
place: '',
maxPeople: 0,
authorNickname: '',
description: '',
});

const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
setInputData({
...inputData,
[e.target.name]: e.target.value,
});
};

const handleRegisterButtonClick = async () => {
if (
inputData.title === '' ||
inputData.date === '' ||
inputData.time === '' ||
inputData.place === '' ||
inputData.maxPeople <= 0 ||
inputData.authorNickname === ''
) {
return;
}

mutate(inputData);
};

return (
<FormLayout>
<FormLayout.Header>모임등록하기</FormLayout.Header>
<FormLayout.Header onBackArrowClick={() => navigate(ENDPOINTS.main)}>
모임등록하기
</FormLayout.Header>

<FormLayout.MainForm>
{Object.entries(Input_Info_List).map(([key, info]) => (
<MoimInput key={key} data={info} />
<MoimInput key={key} data={info} name={key} onChange={handleChange} />
))}
</FormLayout.MainForm>

<FormLayout.BottomButtonWrapper>
<Button shape="bar">등록하기</Button>
<Button shape="bar" onClick={handleRegisterButtonClick}>
등록하기
</Button>
</FormLayout.BottomButtonWrapper>
</FormLayout>
);
Expand Down
3 changes: 1 addition & 2 deletions frontend/src/types/requests.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export interface MoimInfo {
id: number;
title: string;
date: string;
time: string;
Expand All @@ -10,7 +9,7 @@ export interface MoimInfo {
}

export interface GetMoim {
data: MoimInfo[];
data: { moims: MoimInfo[] };
}

export interface PostMoim {
Expand Down