Skip to content

Commit

Permalink
Feat: 어드민 요청주제관리 페이지 퍼블리싱, 일부 로직 구현 (#265)
Browse files Browse the repository at this point in the history
* Feat: admin 요청주제관리 페이지 틀 생성

* Fix: 쿼리키 추가, 공용 폰트 파일 수정

* Feat: 요청주제관리 목록 수정기능 구현
  • Loading branch information
Nahyun-Kang authored Oct 29, 2024
1 parent 4c6f95d commit 7e9c32c
Show file tree
Hide file tree
Showing 12 changed files with 905 additions and 0 deletions.
3 changes: 3 additions & 0 deletions public/icons/plus_gray.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions src/app/_api/adminTopics/editAdminTopic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { editAdminTopicType } from '@/lib/types/requestedTopicType';
//PUT "/admin/topics/{topicId}"

import axiosInstance from '@/lib/axios/axiosInstance';

const editAdminTopic = async ({ topicId, isExposed, categoryCode, title }: editAdminTopicType) => {
await axiosInstance.put(`/admin/topics/${topicId}`, {
isExposed,
categoryCode,
title,
});
};

export default editAdminTopic;
23 changes: 23 additions & 0 deletions src/app/_api/adminTopics/getAdminTopics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// GET "/admin/topics?cursorId={}&size={}"

import axiosInstance from '@/lib/axios/axiosInstance';

interface GetTopicsType {
cursorId?: number | null;
}

const getAdminTopics = async ({ cursorId }: GetTopicsType) => {
const params = new URLSearchParams({
size: '5',
});

if (cursorId) {
params.append('cursorId', cursorId.toString());
}

const response = await axiosInstance.get(`/admin/topics?${params.toString()}`);

return response.data;
};

export default getAdminTopics;
139 changes: 139 additions & 0 deletions src/app/temp-admin-topic/_components/AdminTopicBox.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import { style } from '@vanilla-extract/css';
import { vars } from '@/styles/theme.css';
import * as fonts from '@/styles/font.css';

export const container = style({
width: '100%',
padding: '12px',

display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
gap: '16px',

position: 'relative',

backgroundColor: vars.color.white,
borderRadius: '20px',
cursor: 'pointer',
});

export const wrapper = style({
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
rowGap: '10px',
});

export const topicWrapper = style({
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
columnGap: '8px',
});

export const buttonWrapper = style({
display: 'flex',
flexDirection: 'column',
gap: '10px',
});

export const button = style({
padding: '6px 12px',

width: '80px',

display: 'flex',
alignItems: 'center',
justifyContent: 'center',

flexShrink: 0,

borderRadius: '14px',
});

export const exposeToggleButton = style([
button,
{
backgroundColor: vars.color.blue,
color: vars.color.white,
},
]);

export const editButton = style([
button,
{
border: '1px solid #3D95FF80',
backgroundColor: vars.color.white,
color: vars.color.blue,
},
]);

export const category = style([
fonts.Label,
{
padding: '6px 12px',

border: `0.5px solid ${vars.color.lightgray}`,
borderRadius: '20px',

color: vars.color.lightgray,
},
]);

export const topic = style([fonts.BodyBold, { color: vars.color.black }]);

export const contentWrapper = style([
fonts.Label,
{
width: '100%',
paddingLeft: '4px',

display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',

color: vars.color.black,
},
]);

export const bottomWrapper = style({
width: '100%',
paddingLeft: '4px',

display: 'flex',
flexDirection: 'row',
alignItems: 'center',
gap: '8px',
});

export const author = style({
fontSize: '1.3rem',
color: vars.color.bluegray10,
});

export const anonymous = style({
fontSize: '1.3rem',
color: vars.color.blue,
});

export const click = style({
fontSize: '1.3rem',
color: vars.color.blue,
});

export const addBtn = style({
width: '56px',
height: '56px',

position: 'absolute',
bottom: '12px',
right: '12px',

borderRadius: '50%',
boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',

backgroundColor: vars.color.white,
});
72 changes: 72 additions & 0 deletions src/app/temp-admin-topic/_components/AdminTopicBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'use client';
import { useState } from 'react';
import { useMutation, useQuery } from '@tanstack/react-query';

import BottomSheet from './BottomSheet';

import { RequestedTopicType } from '@/lib/types/requestedTopicType';
import editAdminTopic from '@/app/_api/adminTopics/editAdminTopic';
import * as styles from './AdminTopicBox.css';

interface TopicBoxProps {
topic: RequestedTopicType;
onClick: () => void;
}

function TopicBox({ topic, onClick }: TopicBoxProps) {
const [isBottomSheetOpen, setIsBottomSheetOpen] = useState(false);

const editTopicMutation = useMutation({
// mutationFn: () =>
// editAdminTopic({
// isExposed : !topic.isExposed,
// title,
// categoryCode,
// }),
});

const clickToggleExposeButton = () => {
setIsBottomSheetOpen(true);
editTopicMutation.mutate();
};

return (
<div className={styles.container}>
<div className={styles.wrapper} onClick={onClick}>
<div className={styles.topicWrapper}>
<div className={styles.category}>{topic.categoryKorName}</div>
<div className={styles.topic}>{topic.title}</div>
</div>
<div className={styles.contentWrapper}>
<div>{topic.description}</div>
</div>
<div className={styles.bottomWrapper}>
<div className={styles.author}>{topic.ownerNickname}</div>
<div className={styles.author}>{topic.createdDate}</div>
<div className={styles.anonymous}>{topic.isAnonymous && '익명'}</div>
</div>
{/* <button className={styles.addBtn}>
<PlusIcon />
</button> */}
</div>
<div className={styles.buttonWrapper}>
<button className={styles.exposeToggleButton}>{topic.isExposed ? '노출' : '미노출'}</button>
<button className={styles.editButton} onClick={clickToggleExposeButton}>
수정하기
</button>
</div>
{isBottomSheetOpen && (
<BottomSheet
onClose={() => {
setIsBottomSheetOpen(false);
}}
topicTitle={topic.title}
category={topic.categoryKorName}
isExposed={topic.isExposed}
/>
)}
</div>
);
}

export default TopicBox;
92 changes: 92 additions & 0 deletions src/app/temp-admin-topic/_components/AdminTopicMock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { RequestedTopicType } from '@/lib/types/requestedTopicType';

export const requestedTopicData: RequestedTopicType[] = [
{
categoryEngName: 'culture',
categoryKorName: '문화',
title: '지역 문화 행사 안내',
description: '이번 주말에 진행되는 지역 문화 행사를 안내드립니다.',
createdDate: '2024-10-26',
ownerId: 2,
ownerNickname: '문화팀',
isAnonymous: false,
isExposed: true,
},
{
categoryEngName: 'life',
categoryKorName: '일상생활',
title: '일상생활 팁 공유',
description: '일상생활을 더 편리하게 만들어줄 유용한 팁을 공유합니다.',
createdDate: '2024-10-27',
ownerId: 3,
ownerNickname: '일상고수',
isAnonymous: true,
isExposed: false,
},
{
categoryEngName: 'place',
categoryKorName: '장소',
title: '서울의 숨겨진 명소 추천',
description: '잘 알려지지 않은 서울의 멋진 장소를 소개합니다.',
createdDate: '2024-10-20',
ownerId: 4,
ownerNickname: '여행자',
isAnonymous: false,
isExposed: true,
},
{
categoryEngName: 'music',
categoryKorName: '음악',
title: '이번 주 추천 음악',
description: '가을에 어울리는 음악 리스트를 공유합니다.',
createdDate: '2024-10-21',
ownerId: 5,
ownerNickname: '음악사랑',
isAnonymous: false,
isExposed: true,
},
{
categoryEngName: 'movie_drama',
categoryKorName: '영화/드라마',
title: '최근 본 영화/드라마 리뷰',
description: '최근에 감상한 영화와 드라마에 대한 리뷰를 남깁니다.',
createdDate: '2024-10-22',
ownerId: 6,
ownerNickname: '영화광',
isAnonymous: false,
isExposed: true,
},
{
categoryEngName: 'book',
categoryKorName: '도서',
title: '이번 달 추천 도서',
description: '이달의 추천 도서를 소개합니다. 책을 좋아하는 분들께 추천!',
createdDate: '2024-10-23',
ownerId: 7,
ownerNickname: '책사랑',
isAnonymous: false,
isExposed: true,
},
{
categoryEngName: 'animal_plant',
categoryKorName: '동식물',
title: '우리 집 반려동물 소개',
description: '우리 집 귀여운 반려동물을 소개합니다. 사진 포함!',
createdDate: '2024-10-24',
ownerId: 8,
ownerNickname: '동물사랑',
isAnonymous: true,
isExposed: false,
},
{
categoryEngName: 'etc',
categoryKorName: '기타',
title: '기타 자유 주제',
description: '어떤 주제든 자유롭게 이야기 나누는 공간입니다.',
createdDate: '2024-10-25',
ownerId: 9,
ownerNickname: '자유인',
isAnonymous: false,
isExposed: true,
},
];
Loading

0 comments on commit 7e9c32c

Please sign in to comment.