diff --git a/src/pages/store/Store.tsx b/src/pages/store/Store.tsx
index 87db0e7..74e398b 100644
--- a/src/pages/store/Store.tsx
+++ b/src/pages/store/Store.tsx
@@ -1,3 +1,189 @@
+import { useCallback, useEffect, useRef, useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+import { getUser } from '@/api/userApi';
+import type { ShopItem } from '@/api/shopApi';
+import { getShopNotices, type NoticeInfo } from '@/api/noticeApi';
+import Modal from '@/components/common/Modal';
+import RegisterLayout from '@/components/layout/RegisterLayout';
+import Button from '@/components/common/Button';
+import ic_location from '@/assets/icons/location-red.svg';
+import Post from '@/components/common/Post';
+import Footer from '@/components/layout/Footer';
+
+const NOTICES_LIMIT = 12;
+
export default function Store() {
- return
내 가게 정보 상세(사장님)
;
+ const navigate = useNavigate();
+ const [shop, setShop] = useState(null);
+ const [notices, setNotices] = useState([]);
+ const noticesOffset = useRef(0);
+ const [isModalOpen, setIsModalOpen] = useState(false);
+ const [modalContent, setModalContent] = useState('');
+ const [isLoading, setIsLoading] = useState(false);
+ const observerRef = useRef(null);
+ const [isMobile, setIsMobile] = useState(window.innerWidth < 768);
+
+ const handleClose = useCallback(() => {
+ if (modalContent.startsWith('로그인')) {
+ navigate('/login');
+ } else {
+ setIsModalOpen(false);
+ }
+ }, [navigate, modalContent]);
+
+ const loadNotices = useCallback(async () => {
+ if (!shop || noticesOffset.current < 0) return;
+ setIsLoading(true);
+ try {
+ const noticesResponse = await getShopNotices(shop.id, {
+ offset: noticesOffset.current,
+ limit: NOTICES_LIMIT,
+ });
+ setNotices((prev) => [...prev, ...noticesResponse.items]);
+ if (noticesResponse.hasNext) noticesOffset.current += NOTICES_LIMIT;
+ else noticesOffset.current = -1;
+ setIsLoading(false);
+ } catch {
+ setIsLoading('error');
+ }
+ }, [shop]);
+
+ useEffect(() => {
+ const userId = localStorage.getItem('userId');
+ if (!userId) {
+ setIsModalOpen(true);
+ setModalContent('로그인이 필요합니다.');
+ return;
+ }
+
+ try {
+ (async () => {
+ const userResponse = await getUser(userId);
+ setShop(userResponse.item.shop?.item ?? null);
+ })();
+ } catch (error) {
+ setIsModalOpen(true);
+ setModalContent((error as Error).message);
+ }
+ }, []);
+
+ // 무한 스크롤
+ useEffect(() => {
+ const observer = new IntersectionObserver(
+ (entries) => {
+ if (entries[0].isIntersecting && !isLoading) {
+ loadNotices();
+ }
+ },
+ {
+ rootMargin: '300px',
+ },
+ );
+
+ const { current } = observerRef;
+ if (current) observer.observe(current);
+ return () => {
+ if (current) observer.unobserve(current);
+ };
+ }, [loadNotices, isLoading]);
+
+ // 반응형
+ useEffect(() => {
+ const handleResize = () => {
+ setIsMobile(window.innerWidth < 768);
+ };
+ window.addEventListener('resize', handleResize);
+ return () => window.removeEventListener('resize', handleResize);
+ }, []);
+
+ return (
+
+
+
+
내 가게
+ {shop ? (
+
+
+
+
+
+
+

+
{shop.address1}
+
+
{shop.description}
+
+
+
+
+
+
+
+ ) : (
+
+ )}
+
+
+ {shop && (
+
+
+
+ {notices[0] && '내가 '}등록한 공고
+
+ {notices[0] ? (
+
+ {notices.map((notice) => (
+
+ ))}
+
+ ) : (
+
+ )}
+
+ {/* 스크롤 감지 요소 */}
+
+ {isLoading && (
+
+ {isLoading === 'error'
+ ? '데이터를 불러오는데 실패했습니다.'
+ : '로딩 중...'}
+
+ )}
+
+
+ )}
+
+ {isModalOpen && (
+
+ {modalContent}
+
+ )}
+
+ );
}