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

[분실물] 공지 분실물 기능 #640

Merged
merged 46 commits into from
Jan 25, 2025
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
11aad8b
feat: 분실물 버튼 구현
junghaesung79 Jan 11, 2025
cb4a370
feat: 글쓰기 페이지 추가
junghaesung79 Jan 11, 2025
c1ceb35
refactor: 사용하지 않는 페이지 삭제
junghaesung79 Jan 12, 2025
3a840cc
feat: form 프레임 구현
junghaesung79 Jan 12, 2025
9122341
feat: 달력 기능 추가
junghaesung79 Jan 14, 2025
7561dcf
feat: input 구현
junghaesung79 Jan 14, 2025
b35718e
feat: 사진 업로드
junghaesung79 Jan 14, 2025
e3ddd6a
refactor: 사진 등록 로직 수정
junghaesung79 Jan 15, 2025
9d9c2df
refactor: 참조 문제 수정
junghaesung79 Jan 15, 2025
8c80115
feat: 훅 생성
junghaesung79 Jan 16, 2025
7050398
refactor: 훅 중복 제거
junghaesung79 Jan 20, 2025
ae3a523
feat: 학생회 권한 확인
junghaesung79 Jan 20, 2025
53cb31f
feat: 미입력 경고
junghaesung79 Jan 20, 2025
16f7f97
feat: 모바일 디자인
junghaesung79 Jan 20, 2025
48bdf1f
refactor: 상태 검증 수정
junghaesung79 Jan 20, 2025
14b121f
refactor: api 변경 대응
junghaesung79 Jan 20, 2025
ad88b02
feat: 분실물 공지 조회
junghaesung79 Jan 21, 2025
0805424
refactor: lint 에러 수정 및 폰트 수정
junghaesung79 Jan 22, 2025
fac5896
feat: 모바일 뷰
junghaesung79 Jan 22, 2025
7895a48
refactor: 링크명 수정
junghaesung79 Jan 22, 2025
9e40509
refactor: lint 에러 수정
junghaesung79 Jan 22, 2025
6497f53
refactor: 용어 변경 -> articles
junghaesung79 Jan 22, 2025
e8b9653
refactor: 로딩 스피너 위치 조절
junghaesung79 Jan 22, 2025
b47f8b8
refactor: lint 에러 수정
junghaesung79 Jan 22, 2025
34d978e
refactor: 목록 삭제 버튼 위치 수정
junghaesung79 Jan 23, 2025
4565ace
refactor: 모바일 삭제 모달 수정
junghaesung79 Jan 23, 2025
c7ebd3d
refactor: 이벤트 프로퍼티명 변경
junghaesung79 Jan 23, 2025
d9ce075
feat: 로깅 추가
junghaesung79 Jan 23, 2025
fcb855a
refactor: 로거 훅 수정
junghaesung79 Jan 23, 2025
a73ecd0
refactor: QA 문제 해결
junghaesung79 Jan 23, 2025
e92603b
refactor: 인덱스 페이지 width 변경
junghaesung79 Jan 23, 2025
dd8b86d
refactor: 마진 수정
junghaesung79 Jan 23, 2025
d255a80
refactor: qa 이슈 수정
junghaesung79 Jan 23, 2025
0e543c8
refactor: 앱 컴포넌트 수정
junghaesung79 Jan 24, 2025
ba2d5ef
refactor: 이미지 폼 분리
junghaesung79 Jan 24, 2025
1c32ad2
refactor: key props 문제 해결
junghaesung79 Jan 25, 2025
788d5f5
refactor: 내용 폼 분리
junghaesung79 Jan 25, 2025
9b43d0b
refactor: 습득 장소 폼 분리
junghaesung79 Jan 25, 2025
2df8ae7
refactor: 카테고리 폼 분리
junghaesung79 Jan 25, 2025
fbfdc42
refactor: 오타 수정
junghaesung79 Jan 25, 2025
d1e2776
refactor: image 이동 점 로직 수정
junghaesung79 Jan 25, 2025
9497078
refactor: 삭제 성공 시에만 navigate
junghaesung79 Jan 25, 2025
3c72a28
refactor: lint 에러 수정
junghaesung79 Jan 25, 2025
17e2de0
refactor: 날짜 폼 분리
junghaesung79 Jan 25, 2025
c972a66
refactor: 습득 장소 최대 글자 설정
junghaesung79 Jan 25, 2025
8124fe9
refactor: 분실물 상세 페이지 이미지 컴포넌트 분리
junghaesung79 Jan 25, 2025
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
17 changes: 11 additions & 6 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import AuthPage from 'pages/Auth/AuthPage';
import LoginPage from 'pages/Auth/LoginPage';
import BoardPage from 'pages/BoardPage';
import StorePage from 'pages/Store/StorePage';
import NoticePage from 'pages/Notice/NoticePage';
import NoticeListPage from 'pages/Notice/NoticeListPage';
import NoticeDetailPage from 'pages/Notice/NoticeDetailPage';
import ArticlesPage from 'pages/Articles/ArticlesPage';
import ArticleListPage from 'pages/Articles/ArticleListPage';
import ArticlesDetailPage from 'pages/Articles/ArticlesDetailPage';
import Toast from 'components/common/Toast';
import LogPage from 'components/common/LogPage';
import SignupPage from 'pages/Auth/SignupPage';
Expand All @@ -35,6 +35,8 @@ import ModifyTimetablePage from 'pages/TimetablePage/ModifyTimetablePage';
import PageNotFound from 'pages/Error/PageNotFound';
import PolicyPage from 'pages/PolicyPage';
import ROUTES from 'static/routes';
import LostItemPage from 'pages/Articles/LostItemPage';
import LostItemDetailPage from 'pages/Articles/LostItemDetailPage';

interface HelmetWrapperProps {
title: string;
Expand Down Expand Up @@ -75,10 +77,13 @@ function App() {
<Route path={ROUTES.BusCourse()} element={<HelmetWrapper title="코인 - 버스" element={<BusCoursePage />} />} />
<Route path={ROUTES.Cafeteria()} element={<HelmetWrapper title="코인 - 식단" element={<CafeteriaPage />} />} />
<Route path={ROUTES.PrivatePolicy()} element={<HelmetWrapper title="코인 - 개인정보 처리방침" element={<PolicyPage />} />} />
<Route path={ROUTES.BoardNotice()} element={<HelmetWrapper title="코인 - 공지사항" element={<NoticePage />} />}>
<Route path={ROUTES.BoardNotice()} element={<NoticeListPage />} />
<Route path={ROUTES.BoardNoticeDetail({ isLink: false })} element={<HelmetWrapper title="코인 - 공지사항 상세" element={<NoticeDetailPage />} />} />
<Route path={ROUTES.Articles()} element={<HelmetWrapper title="코인 - 공지사항" element={<ArticlesPage />} />}>
<Route path={ROUTES.Articles()} element={<ArticleListPage />} />
<Route path={ROUTES.ArticlesDetail({ isLink: false })} element={<HelmetWrapper title="코인 - 공시사항 상세" element={<ArticlesDetailPage />} />} />
<Route path={ROUTES.LostItemDetail({ isLink: false })} element={<HelmetWrapper title="코인 - 분실물 상세" element={<LostItemDetailPage />} />} />
</Route>
<Route path={ROUTES.LostItemFound()} element={<PrivateRoute requireAuthentication element={<HelmetWrapper title="코인 - 분실물 글쓰기" element={<LostItemPage />} />} />} />
<Route path={ROUTES.LostItemLost()} element={<PrivateRoute requireAuthentication element={<HelmetWrapper title="코인 - 분실물 글쓰기" element={<LostItemPage />} />} />} />
<Route path={ROUTES.Room()} element={<HelmetWrapper title="코인 - 복덕방" element={<RoomPage />} />} />
<Route path={ROUTES.RoomDetail({ isLink: false })} element={<HelmetWrapper title="코인 - 복덕방 상세" element={<RoomDetailPage />} />} />
<Route path={ROUTES.CampusInfo()} element={<HelmetWrapper title="코인 - 교내 시설물 정보" element={<CampusInfo />} />} />
Expand Down
89 changes: 89 additions & 0 deletions src/api/articles/APIDetail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { APIRequest, HTTP_METHOD } from 'interfaces/APIRequest';
import {
ArticlesResponse,
ArticleResponse,
HotArticlesResponse,
SingleLostItemArticleResponseDTO,
LostItemArticlesResponseDTO,
LostItemResponse,
LostItemArticlesRequestDTO,
} from './entity';

export class GetArticles<R extends ArticlesResponse> implements APIRequest<R> {
method = HTTP_METHOD.GET;

path: string;

response!: R;

constructor(page: string | undefined) {
this.path = `/articles?page=${page}&limit=10`;
}
}

export class GetArticle<R extends ArticleResponse> implements APIRequest<R> {
method = HTTP_METHOD.GET;

path: string;

response!: R;

constructor(id: string | undefined) {
this.path = `/articles/${id}`;
}
}

export class GetHotArticles<R extends HotArticlesResponse> implements APIRequest<R> {
method = HTTP_METHOD.GET;

path = '/articles/hot';

response!: R;
}

export class GetLostItemArticles<R extends LostItemArticlesResponseDTO> implements APIRequest<R> {
method = HTTP_METHOD.GET;

path = '/articles/lost-item';

response!: R;
}

export class GetSingleLostItemArticle<R
extends SingleLostItemArticleResponseDTO> implements APIRequest<R> {
method = HTTP_METHOD.GET;

path: string;

response!: R;

constructor(id: number) {
this.path = `/articles/lost-item/${id}`;
}
}

export class PostLostItemArticles<R extends LostItemResponse> implements APIRequest<R> {
method = HTTP_METHOD.POST;

path = '/articles/lost-item';

response!: R;

auth = true;

constructor(public authorization: string, public data: LostItemArticlesRequestDTO) { }
}

export class DeleteLostItemArticle<R extends LostItemResponse> implements APIRequest<R> {
method = HTTP_METHOD.DELETE;

path: string;

response!: R;

auth = true;

constructor(public authorization: string, id: number) {
this.path = `/articles/lost-item/${id}`;
}
}
118 changes: 118 additions & 0 deletions src/api/articles/entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { APIResponse } from 'interfaces/APIResponse';

export interface GetArticlesRequest {
boardId: string
page: string
}

export interface Article {
id: number
board_id: number
title: string
author: string
hit: number
registered_at: string // yyyy-MM-dd 아우누리에 게시판에 등록된 날짜
updated_at: string // yyyy-MM-dd HH:mm:ss 이하 형식 동일
}

export interface Attachment {
id: 1,
name: string,
url: string,
created_at: string,
updated_at: string,
}

export interface PaginationInfo {
total_count: number
current_count: number
total_page: number
current_page: number
}

export interface PaginatedResponse<T> extends PaginationInfo, APIResponse {
articles: T[];
}

export type ArticlesResponse = PaginatedResponse<Article>;
export type ArticlesSearchResponse = PaginatedResponse<Article>;

export interface ArticleResponse extends Article, APIResponse {
content: string;
attachments: Attachment[];
prev_id: number;
next_id: number;
}

export interface HotArticle extends Article { }

export type HotArticlesResponse = HotArticle[];

// GET /articles/lost-item
interface LostItemArticleForGetDTO {
id: number;
board_id: number;
category: string;
found_place: string;
found_date: string;
content: string;
author: string;
registered_at: string;
updated_at: string;
}

export interface LostItemArticlesResponseDTO extends APIResponse {
articles: LostItemArticleForGetDTO[];
total_count: number;
current_count: number;
total_page: number;
current_page: number;
}

interface ImageDTO {
id: number;
image_url: string;
}

export interface SingleLostItemArticleResponseDTO extends APIResponse {
id: number;
board_id: number;
category: string;
found_place: string;
found_date: string;
content: string;
author: string;
images: ImageDTO[];
prev_id: number | null;
next_id: number | null;
registered_at: string; // yyyy-MM-dd
updated_at: string; // yyyy-MM-dd HH:mm:ss
}

export interface LostItemResponse extends APIResponse {
id: number;
board_id: number;
category: string;
found_place: string;
found_date: string;
content: string;
author: string;
images: ImageDTO[];
prev_id: number | null;
next_id: number | null;
registered_at: string;
updated_at: string;
}

// POST /articles/lost-item
interface LostItemArticleForPostDTO {
category: string;
found_place: string;
found_date: string; // yyyy-MM-dd
content: string;
images: string[];
}

export interface LostItemArticlesRequestDTO {
articles: Array<LostItemArticleForPostDTO>;
}
24 changes: 24 additions & 0 deletions src/api/articles/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import APIClient from 'utils/ts/apiClient';
import {
GetArticles,
GetHotArticles,
GetArticle,
GetLostItemArticles,
GetSingleLostItemArticle,
DeleteLostItemArticle,
PostLostItemArticles,
} from './APIDetail';

export const getArticles = APIClient.of(GetArticles);

export const getArticle = APIClient.of(GetArticle);

export const getHotArticles = APIClient.of(GetHotArticles);

export const getLostItemArticles = APIClient.of(GetLostItemArticles);

export const getSingleLostItemArticle = APIClient.of(GetSingleLostItemArticle);

export const postLostItemArticle = APIClient.of(PostLostItemArticles);

export const deleteLostItemArticle = APIClient.of(DeleteLostItemArticle);
13 changes: 7 additions & 6 deletions src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
export * as abTest from './abTest';
export * as auth from './auth';
export * as store from './store';
export * as dept from './dept';
export * as timetable from './timetable';
export * as bus from './bus';
export * as notice from './notice';
export * as room from './room';
export * as cafeteria from './cafeteria';
export * as coopshop from './coopshop';
export * as dept from './dept';
export * as articles from './articles';
export * as review from './review';
export * as abTest from './abTest';
export * as room from './room';
export * as store from './store';
export * as timetable from './timetable';
export * as uploadFile from './uploadFile';
54 changes: 0 additions & 54 deletions src/api/notice/APIDetail.ts

This file was deleted.

49 changes: 0 additions & 49 deletions src/api/notice/entity.ts

This file was deleted.

Loading
Loading