From c56e5e17d091f462fad1466d27b0b1a088d35e62 Mon Sep 17 00:00:00 2001 From: wooooooooook Date: Sun, 26 Apr 2026 17:15:28 +0900 Subject: [PATCH] =?UTF-8?q?feat.=20=EB=A9=94=EC=9D=B8=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `youtube embed` 라이브러리 설치 - `api` 요청시 로그 출력 코드 제거 - `category-filter.tsx` 카테고리 필터 컴포넌트 추가 --- api/apiClient.ts | 20 +- api/menu.ts | 20 +- app/_components/Page2.tsx | 54 ---- app/_components/all-screen.tsx | 306 ++++++++++++++++++ .../{notice-page.tsx => notice-screen.tsx} | 41 +-- app/index.tsx | 14 +- assets/news-default-thumbnail.jpg | Bin 0 -> 15878 bytes components/ui/category-filter.tsx | 36 +++ components/youtube-embed.d.ts | 6 + components/youtube-embed.native.tsx | 11 + components/youtube-embed.web.tsx | 18 ++ hooks/useMenuData.ts | 60 ++-- package.json | 2 + pnpm-lock.yaml | 91 ++++-- 14 files changed, 511 insertions(+), 168 deletions(-) delete mode 100644 app/_components/Page2.tsx create mode 100644 app/_components/all-screen.tsx rename app/_components/{notice-page.tsx => notice-screen.tsx} (72%) create mode 100644 assets/news-default-thumbnail.jpg create mode 100644 components/ui/category-filter.tsx create mode 100644 components/youtube-embed.d.ts create mode 100644 components/youtube-embed.native.tsx create mode 100644 components/youtube-embed.web.tsx diff --git a/api/apiClient.ts b/api/apiClient.ts index 99486b2..bdd9ba2 100644 --- a/api/apiClient.ts +++ b/api/apiClient.ts @@ -1,8 +1,4 @@ -import axios, { - AxiosError, - type AxiosInstance, - type InternalAxiosRequestConfig, -} from 'axios'; +import axios, { AxiosError, type AxiosInstance, type InternalAxiosRequestConfig } from 'axios'; import { clearTokens, getAccessToken, @@ -96,11 +92,11 @@ apiClient.interceptors.request.use(async (config) => { } if (__DEV__) { - console.log('[api/request]', { - method: config.method, - url: config.url, - hasAuthorization: !!config.headers.Authorization, - }); + // console.log('[api/request]', { + // method: config.method, + // url: config.url, + // hasAuthorization: !!config.headers.Authorization, + // }); } return config; @@ -131,7 +127,7 @@ const reissueAccessToken = async (): Promise => { Authorization: `Bearer ${refreshToken}`, 'X-Client-Type': MOBILE_CLIENT_TYPE, }, - }, + } ); const newAccessToken = data?.data?.accessToken ?? data?.accessToken; @@ -220,7 +216,7 @@ apiClient.interceptors.response.use( } finally { isRefreshing = false; } - }, + } ); export default apiClient; diff --git a/api/menu.ts b/api/menu.ts index 2bb968b..d8e9399 100644 --- a/api/menu.ts +++ b/api/menu.ts @@ -7,7 +7,7 @@ export interface ApiResponse { timestamp: string; } -export type MenuCategory = "BREAKFAST" | "LUNCH" | "DINNER"; +export type MenuCategory = 'BREAKFAST' | 'LUNCH' | 'DINNER'; export interface MenuItem { date: string; @@ -17,25 +17,25 @@ export interface MenuItem { export const getMenus = async (): Promise => { if (__DEV__) { - console.log("[menus/api] GET /menus 요청 시작"); + // console.log("[menus/api] GET /menus 요청 시작"); } try { - const res = await apiClient.get>("/menus"); + const res = await apiClient.get>('/menus'); if (__DEV__) { - console.log("[menus/api] GET /menus 응답 성공", { - status: res.status, - apiStatus: res.data.status, - count: res.data.data.length, - firstItem: res.data.data[0], - }); + // console.log("[menus/api] GET /menus 응답 성공", { + // status: res.status, + // apiStatus: res.data.status, + // count: res.data.data.length, + // firstItem: res.data.data[0], + // }); } return res.data.data; } catch (error) { if (__DEV__) { - console.error("[menus/api] GET /menus 응답 실패", error); + console.error('[menus/api] GET /menus 응답 실패', error); } throw error; diff --git a/app/_components/Page2.tsx b/app/_components/Page2.tsx deleted file mode 100644 index ddbe4b6..0000000 --- a/app/_components/Page2.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { Button } from '@/components/ui/button'; -import { Icon } from '@/components/ui/icon'; -import { Text } from '@/components/ui/text'; -import { Link } from 'expo-router'; -import { StarIcon } from 'lucide-react-native'; -import { useColorScheme } from 'nativewind'; -import * as React from 'react'; -import { Image, type ImageStyle, View } from 'react-native'; - -const LOGO = { - light: require('@/assets/images/react-native-reusables-light.png'), - dark: require('@/assets/images/react-native-reusables-dark.png'), -}; - -const IMAGE_STYLE: ImageStyle = { - height: 76, - width: 76, -}; - -export function Page2() { - const { colorScheme } = useColorScheme(); - - return ( - - - - - 1. Edit app/index.tsx to get started. - - - 2. Save to see your changes instantly. - - - - - - - - - - - - - - - ); -} diff --git a/app/_components/all-screen.tsx b/app/_components/all-screen.tsx new file mode 100644 index 0000000..e8bf5b8 --- /dev/null +++ b/app/_components/all-screen.tsx @@ -0,0 +1,306 @@ +import { Text } from '@/components/ui/text'; +import * as React from 'react'; +import { Link } from 'expo-router'; +import { Image, ScrollView, TouchableOpacity, View } from 'react-native'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import { YoutubeEmbed } from '@/components/youtube-embed'; +import { Footer } from './footer'; +import { ArrowRightIcon, ChatBubbleIcon, DiningIcon, HeartIcon } from '@/components/icons'; +import { CategoryFilter } from '@/components/ui/category-filter'; + +type Props = { + onNavigate: (tabIndex: number) => void; +}; + +const NOTICE_CATEGORIES = ['전체', '일반', '장학', '진로', '학생활동', '학칙개정']; +const NEWSPAPER_CATEGORIES = ['전체', '보도', '사회']; + +export default function AllScreen({ onNavigate }: Props) { + const insets = useSafeAreaInsets(); + const [selectedNoticeCategory, setSelectedNoticeCategory] = React.useState('전체'); + const [selectedNewspaperCategory, setSelectedNewspaperCategory] = React.useState('전체'); + + return ( + + + {/* 식단 */} + + onNavigate(1)}> + + + + 1월 21일 (화) 점심 + + 등록된 식단 내용이 없습니다. + + + + + {/* 공지사항 */} + + + 공지사항 + onNavigate(4)} className="me-3.5"> + + + + + + + + {NOTICE_DUMMY_DATA.map((item, index) => ( + + + {item.title} + {item.time} + + + ))} + + + + {/* 학사일정 */} + + + 학사일정 + onNavigate(5)} className="me-3.5"> + + + + + {SCHEDULE_DUMMY_DATA.date} + + + {SCHEDULE_DUMMY_DATA.items.map((item, index) => ( + + {item.date} + + {item.category} {item.title} + + + ))} + + + + {/* 게시판 */} + + + 게시판 + onNavigate(2)} className="me-3.5"> + + + + + {POSTS_DUMMY_DATA.map((item) => ( + + + + {item.category} + + {item.title} + + + + {item.date} + + {item.likes} + + {item.comments} + + + + ))} + + + + {/* 명대신문 */} + + + 명대신문 + onNavigate(6)} className="me-3.5"> + + + + + + + + {MJU_NEWSPAPER_DUMMY_DATA.map((item, index) => ( + + + + + + {item.title} + + + {item.preview} + + + {item.author} + + + {item.date} + + + + + ))} + + + + {/* 명대뉴스 */} + + + 명대뉴스 + onNavigate(7)} className="me-3.5"> + + + + + {MJU_NEWS_DUMMY_DATA.map((item, index) => ( + + + + + + + + + {item.title} + + + {item.date} + + + + + + ))} + + + +