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

feat: 리뷰 등록 step 1,2,3 페이지 구현 #162

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
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
3 changes: 2 additions & 1 deletion src/apis/beers/getBeer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useQuery } from 'react-query';

import request from '@/commons/axios';
import { queryKeyFactory } from '@/commons/queryKeyFactory';
import { IBaseResponse, IBeer } from '@/types';

interface IGetBeerResponseData extends IBaseResponse<IBeer> {}
Expand All @@ -18,7 +19,7 @@ export const getBeer = async (beerId: number) => {
};

export const useGetBeer = (beerId: IBeer['id'], initialData?: IBeer) => {
const result = useQuery(['beer', beerId], () => getBeer(beerId), {
const result = useQuery(queryKeyFactory.GET_BEER(beerId), () => getBeer(beerId), {
cacheTime: Infinity,
initialData,
enabled: !!beerId,
Expand Down
45 changes: 45 additions & 0 deletions src/apis/review/createReview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useMutation, useQueryClient } from 'react-query';

import request from '@/commons/axios';
import { queryKeyFactory } from '@/commons/queryKeyFactory';
import { IBaseResponse, IReview } from '@/types';

/**
* 리뷰 등록
*/

export interface ICreateReviewResponseData extends IBaseResponse<IReview> {}

export interface ICreateReviewPayload {
beerId: number;
content: string;
feelStatus: number;
imageUrl: string;
isPublic: boolean;
flavorIds: number[];
}

export const createReview = async (payload: ICreateReviewPayload) => {
const res = await request<ICreateReviewResponseData>({
method: 'post',
url: '/api/v1/reviews',
data: { payload },
});

return res.data;
};

export const useCreateReviewMutation = () => {
const cache = useQueryClient();

const { mutateAsync: createReviewMutation, ...rest } = useMutation(createReview, {
onSuccess: async () => {
await cache.invalidateQueries(queryKeyFactory.GET_REVIEW());
},
});

return {
createReview: createReviewMutation,
...rest,
};
};
16 changes: 16 additions & 0 deletions src/apis/review/deleteReview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { IGetReview } from '@/apis/review/getReview';
import request from '@/commons/axios';

/**
* 나의 리뷰 삭제
*/

export const deleteReview = async (id?: number) => {
const res = await request<IGetReview>({
method: 'delete',
url: '/api/v1/reviews',
params: { id },
});

return res.data;
};
18 changes: 18 additions & 0 deletions src/apis/review/getReview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import request from '@/commons/axios';
import { IBaseResponse, IReview } from '@/types';

export interface IGetReview extends IBaseResponse<IReview> {}

/**
* 나의 리뷰 조회
*/

export const getReview = async (id?: number) => {
const res = await request<IGetReview>({
method: 'get',
url: '/api/v1/reviews',
params: { id },
});

return res.data;
};
49 changes: 49 additions & 0 deletions src/apis/review/getReviews.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { useQuery } from 'react-query';

import request from '@/commons/axios';
import { queryKeyFactory } from '@/commons/queryKeyFactory';
import { IBaseResponse, IBeer, IReview } from '@/types';

export interface IGetReviews extends IBaseResponse<IReview[]> {}

/**
* 맥주별 reviews 조회
*/

export const getReviewsByBeer = async (beerId: number) => {
const res = await request<IGetReviews>({
method: 'get',
url: '/api/v1/reviews',
params: {
beerId,
},
});

return res.data;
};

// @todo: 페이지네이션 구현

export const useGetReviewsByBeer = (beerId: IBeer['id'], initialData?: IReview[]) => {
const result = useQuery(queryKeyFactory.GET_REVIEWS(beerId), () => getReviewsByBeer(beerId), {
cacheTime: Infinity,
initialData,
enabled: !!beerId,
});

return result;
};

/**
* 나의 리뷰 목록 조회
*/

export const getMyReviews = async (limit?: number) => {
const res = await request<IGetReviews>({
method: 'get',
url: '/api/v1/reviews/me',
data: { limit },
});

return res.data;
};
106 changes: 4 additions & 102 deletions src/apis/review/index.ts
Original file line number Diff line number Diff line change
@@ -1,102 +1,4 @@
import { useQuery } from 'react-query';

import request from '@/commons/axios';
import { IBaseResponse, IBeer, IReview } from '@/types';

export interface IGetReview extends IBaseResponse<IReview> {}
export interface IGetReviews extends IBaseResponse<IReview[]> {}

/**
* 맥주별 reviews 조회
*/

export const getReviewsByBeer = async (beerId: number) => {
const res = await request<IGetReviews>({
method: 'get',
url: '/api/v1/reviews',
params: {
beerId,
},
});

return res.data;
};

// @todo: 페이지네이션 구현

export const useGetReviewsByBeer = (beerId: IBeer['id'], initialData?: IReview[]) => {
const result = useQuery(['reviews', beerId], () => getReviewsByBeer(beerId), {
cacheTime: Infinity,
initialData,
enabled: !!beerId,
});

return result;
};

/**
* 리뷰 등록
*/

export interface ICreateReviewResponseData extends IBaseResponse<IReview> {}

export interface ICreateReviewPayload {
beerId: number;
content: string;
feelStatus: number;
imageUrl: string;
isPublic: boolean;
flavorIds: number[];
}

export const postReview = async (payload: ICreateReviewPayload) => {
const res = await request<ICreateReviewResponseData>({
method: 'post',
url: '/api/v1/reviews',
data: { payload },
});

return res.data;
};

/**
* 나의 리뷰 조회
*/

export const getReview = async (id?: number) => {
const res = await request<IGetReview>({
method: 'get',
url: '/api/v1/reviews',
params: { id },
});

return res.data;
};

/**
* 나의 리뷰 삭제
*/

export const deleteReview = async (id?: number) => {
const res = await request<IGetReview>({
method: 'delete',
url: '/api/v1/reviews',
params: { id },
});

return res.data;
};

/**
* 나의 리뷰 목록 조회
*/

export const getMyReviews = async (limit?: number) => {
const res = await request<IGetReviews>({
method: 'get',
url: '/api/v1/reviews/me',
data: { limit },
});

return res.data;
};
export * from './createReview';
export * from './getReview';
export * from './getReviews';
export * from './deleteReview';
19 changes: 16 additions & 3 deletions src/apis/upload/uploadImage.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { useMutation } from 'react-query';
import { useMutation, useQueryClient } from 'react-query';

import { createReview } from '@/apis/review';
import request from '@/commons/axios';
import { queryKeyFactory } from '@/commons/queryKeyFactory';
import { IBaseResponse, IImage } from '@/types';

interface IUploadImageResponseData extends IBaseResponse<IImage> {}
Expand All @@ -22,6 +24,17 @@ export const uploadImage = async (image: FormData) => {
return res.data;
};

export const useUploadImage = () => {
return useMutation(uploadImage);
export const useUploadImageMutation = () => {
const cache = useQueryClient();

const { mutateAsync: uploadImageMutation, ...rest } = useMutation(uploadImage, {
onSuccess: async () => {
await cache.invalidateQueries(queryKeyFactory.UPLOAD_IMAGE());
},
});

return {
uploadImage: uploadImageMutation,
...rest,
};
};
6 changes: 6 additions & 0 deletions src/commons/queryKeyFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@
*/

import { IGetBeersParams } from '@/apis/beers/getBeers';
import { IBeer } from '@/types';

export const queryKeyFactory = {
FETCH_TEST: () => ['FETCH_TEST'],
GET_BEER: (beerId: IBeer['id']) => ['GET_BEER', beerId],
GET_BEERS: (payload?: Omit<IGetBeersParams, 'offset'>) => ['GET_BEERS', payload],
GET_BEERS_STATISTIC: () => ['GET_BEERS_STATISTIC'],
GET_BEER_RECOMMENDS: () => ['GET_BEER_RECOMMENDS'],
GET_BEER_LIKES: () => ['GET_BEER_LIKES'],
GET_BEER_TYPES: () => ['GET_BEER_TYPES'],
GET_CONTINENTS: () => ['GET_CONTINENTS'],
GET_COUNTRIES: (continentId?: number) => ['GET_COUNTRIES', continentId],
GET_REVIEWS: (beerId: IBeer['id']) => ['GET_REVIEWS', beerId],
CREATE_REVIEW: () => ['CREATE_REVIEW'],
GET_REVIEW: () => ['GET_REVIEW'],
UPLOAD_IMAGE: () => ['UPLOAD_IMAGE'],
};
6 changes: 3 additions & 3 deletions src/components/BeerTicket/BeerTicketTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,12 @@ const BeerTicketTitle: React.FC<BeerTicketTitleProps> = ({
{sliceAndUpperCase(beer?.country?.engName || 'non', 3)}
</span>
<div className="ticket-detail">
{`${beer?.alcohol?.toFixed(1)}%`}
{beer?.alcohol ? `${beer.alcohol?.toFixed(1)}%` : '-'}
Copy link
Contributor

Choose a reason for hiding this comment

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

'?' 없어도 괜찮을 것 같아요!

Suggested change
{beer?.alcohol ? `${beer.alcohol?.toFixed(1)}%` : '-'}
{beer?.alcohol ? `${beer.alcohol.toFixed(1)}%` : '-'}

<span className="ticket-detail-split-dot">{'•'}</span>
{beer?.type?.korName}
{beer?.type?.korName ?? '-'}
</div>
</div>
<span className="ticket-beer-name">{beer?.korName}</span>
<span className="ticket-beer-name">{beer?.korName ?? '-'}</span>
</StyledBeerTicketTitle>
);
};
Expand Down
2 changes: 1 addition & 1 deletion src/components/layouts/SwiperLayout/SwiperLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const SwiperLayout: React.FC<SwiperLayoutProps> = ({

return (
<StyledSwiperLayout className={className}>
<StyledSwiper swipeable={false} selectedItem={pageIndex} currentSlide={0} {...props}>
<StyledSwiper swipeable={false} selectedItem={pageIndex} currentSlide={pageIndex} {...props}>
{React.Children.map(children || undefined, (child) => {
return child
? React.createElement(child.type, {
Expand Down
60 changes: 60 additions & 0 deletions src/constants/dummy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,66 @@ export const MOCK_FLAVORS: IFlavor[] = [
id: 3,
content: '쓴 맛이 나요',
},
{
id: 4,
content: '쓴 맛이 나요',
},
{
id: 5,
content: '쓴 맛이 나요',
},
{
id: 6,
content: '단 맛이나요',
},
{
id: 7,
content: '목넘김이 부드러워요',
},
{
id: 8,
content: '쓴 맛이 나요',
},
{
id: 9,
content: '쓴 맛이 나요',
},
{
id: 10,
content: '쓴 맛이 나요',
},
{
id: 11,
content: '쓴 맛이 나요',
},
{
id: 12,
content: '쓴 맛이 나요',
},
{
id: 13,
content: '쓴 맛이 나요',
},
{
id: 14,
content: '쓴 맛이 나요',
},
{
id: 15,
content: '쓴 맛이 나요',
},
{
id: 16,
content: '쓴 맛이 나요',
},
{
id: 17,
content: '쓴 맛이 나요',
},
{
id: 18,
content: '쓴 맛이 나요',
},
];

export const MOCK_COUNTRY: ICountry = {
Expand Down
Loading