diff --git a/index.html b/index.html index 5085c2f..e31b9b1 100644 --- a/index.html +++ b/index.html @@ -73,9 +73,12 @@ - + - + + + +
+
{highlightKeyword( post.contentPreview.length > 50 ? post.contentPreview.slice(0, 50) + '…' @@ -71,6 +71,7 @@ const PostItem = ({ post, keyword = '' }: PostItemProps) => { alt="thumbnail" className="w-full h-full object-cover" loading="lazy" + decoding="async" /> {(post.imageCount ?? 0) > 1 && (
신고하기
{content || ''}
영업시간 정보 없음
{content}
{category}
{address}
업데이트 {dayjs(updatedDate).format('YYYY.MM.DD')}
{store.storeName}
다녀오셨나요?
리뷰를 통해 경험을 공유해주세요!
최근 리뷰 {reviewCount}개
태그를 선택해주세요 {' '} (최대 5개)
메뉴가 어땠나요?
{storeCategory}
{storeAddress}
사진을 추가해주세요 {' '} @@ -103,6 +114,8 @@ const UploadImage: React.FC = ({ onFileSelect }) => { src={preview} alt="preview" className="w-full h-full object-cover" + loading="lazy" + decoding="async" /> { - + {store.category} {store.name} - + {store.address} {store.representativeTag && ( - + {store.representativeTag} @@ -107,7 +107,7 @@ const StoreItem = ({ store }: StoreItemProps) => { - + {store.ratingAvg} @@ -124,7 +124,7 @@ const StoreItem = ({ store }: StoreItemProps) => { {likeCount} diff --git a/src/components/common/BottomSheetForm.tsx b/src/components/common/BottomSheetForm.tsx index 9300a62..48984d5 100644 --- a/src/components/common/BottomSheetForm.tsx +++ b/src/components/common/BottomSheetForm.tsx @@ -1,5 +1,6 @@ import React, { useState, useEffect } from 'react'; import ProfileImg from '@/assets/svgs/common/profile-img.svg'; +import OptimizedImage from './OptimizedImage'; interface BottomSheetFormProps { title: string; @@ -61,7 +62,7 @@ const BottomSheetForm: React.FC = ({ {storeInfo.category && ( - + {storeInfo.category} )} @@ -81,13 +82,13 @@ const BottomSheetForm: React.FC = ({ {reviewInfo && ( - + {reviewInfo.userName} - + {reviewInfo.content} @@ -97,13 +98,13 @@ const BottomSheetForm: React.FC = ({ {commentInfo && ( - + {commentInfo.nickname} - + {commentInfo.content.length > 30 ? commentInfo.content.slice(0, 30) + '...' : commentInfo.content} @@ -115,13 +116,13 @@ const BottomSheetForm: React.FC = ({ {postInfo && ( - + {postInfo.nickname} - + {postInfo.content.length > 30 ? postInfo.content.slice(0, 30) + '...' : postInfo.content} @@ -130,7 +131,7 @@ const BottomSheetForm: React.FC = ({ )} {/*공통*/} - + {question} @@ -151,9 +152,9 @@ const BottomSheetForm: React.FC = ({ /> {/* 커스텀 원 */} - + {selected === option && ( - + )} {option} @@ -173,7 +174,7 @@ const BottomSheetForm: React.FC = ({ 보내주신 의견은 운영팀이 검토 후 반영됩니다 - + = ({ heightClass = 'auto', widthClass = 'w-full', bgColorClass = 'bg-[#FFF]', - textColorClass = 'text-[#616161]', + textColorClass = 'text-text-gray', className = '', }) => { return ( {text} diff --git a/src/components/common/ConfirmModal.tsx b/src/components/common/ConfirmModal.tsx index dfa9191..61fa89d 100644 --- a/src/components/common/ConfirmModal.tsx +++ b/src/components/common/ConfirmModal.tsx @@ -32,7 +32,7 @@ const ConfirmModal: React.FC = ({ onClick={onDelete} heightClass="h-[44px]" widthClass="w-1/2" - bgColorClass="bg-[#919191]" + bgColorClass="bg-main-gray" textColorClass="text-white" /> diff --git a/src/components/common/ConfirmToast.tsx b/src/components/common/ConfirmToast.tsx index df31dd9..db85e5b 100644 --- a/src/components/common/ConfirmToast.tsx +++ b/src/components/common/ConfirmToast.tsx @@ -1,5 +1,6 @@ import React from 'react'; import ConfirmIcon from '@/assets/svgs/common/confirm-icon.svg'; +import OptimizedImage from './OptimizedImage'; interface ConfirmToastProps { text: string | string[]; @@ -7,8 +8,8 @@ interface ConfirmToastProps { const ConfirmToast: React.FC = ({ text }) => { return ( - - + + {Array.isArray(text) ? ( text.map((line, idx) => {line}) diff --git a/src/components/common/DeleteModal.tsx b/src/components/common/DeleteModal.tsx index ab29abb..6d817ea 100644 --- a/src/components/common/DeleteModal.tsx +++ b/src/components/common/DeleteModal.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { createPortal } from 'react-dom'; import TrashIcon from '@/assets/svgs/review/trash.svg'; import Button from '@/components/common/Button'; +import OptimizedImage from './OptimizedImage'; interface DeleteModalProps { title: string; @@ -20,10 +21,10 @@ const DeleteModal: React.FC = ({ - + {title} - + {description} @@ -40,7 +41,7 @@ const DeleteModal: React.FC = ({ onClick={onDelete} heightClass="h-[44px]" widthClass="w-1/2" - bgColorClass="bg-[#919191]" + bgColorClass="bg-main-gray" textColorClass="text-white" /> diff --git a/src/components/common/Dropdown.tsx b/src/components/common/Dropdown.tsx index 8b3ab3a..1545c38 100644 --- a/src/components/common/Dropdown.tsx +++ b/src/components/common/Dropdown.tsx @@ -44,11 +44,11 @@ const Dropdown = ({ onSelect ,options}: DropdownProps) => { return ( setIsOpen(!isOpen)} - className="flex items-center gap-[4px] font-pretendard text-[#616161] text-[14px] not-italic font-regular leading-[18px]" + className="flex items-center gap-[4px] font-pretendard text-text-gray text-[14px] not-italic font-regular leading-[18px]" > {selected} @@ -56,7 +56,7 @@ const Dropdown = ({ onSelect ,options}: DropdownProps) => { {isOpen && ( @@ -64,7 +64,7 @@ const Dropdown = ({ onSelect ,options}: DropdownProps) => { handleSelect(option)} - className="px-[12px] py-[4px] font-pretendard text-center text-[#616161] text-[14px] font-regular leading-[20px] cursor-pointer hover:text-white hover:bg-main-color" + className="px-[12px] py-[4px] font-pretendard text-center text-text-gray text-[14px] font-regular leading-[20px] cursor-pointer hover:text-white hover:bg-main-color" > {option} diff --git a/src/components/common/FloatingButton.tsx b/src/components/common/FloatingButton.tsx index db43f0d..34804fa 100644 --- a/src/components/common/FloatingButton.tsx +++ b/src/components/common/FloatingButton.tsx @@ -3,6 +3,7 @@ import AddIcon from '@/assets/svgs/common/add-icon.svg'; import { useLoginStatus } from '@/hooks/useLoginStatus'; import LoginRequiredBottomSheet from './LoginRequiredBottomSheet'; import { useState } from 'react'; +import OptimizedImage from './OptimizedImage'; const FloatingButton = () => { const navigate = useNavigate(); @@ -29,8 +30,9 @@ const FloatingButton = () => { onClick={handleClick} className="bg-main-color shadow-floating flex gap-[8px] items-center px-[20px] py-[12px] rounded-[24px] w-[104px] h-[43px] text-[15px] text-white text-cursor-pointer z-50" > - 글쓰기 diff --git a/src/components/common/GreenButton.tsx b/src/components/common/GreenButton.tsx index cf2cddd..06fb8d8 100644 --- a/src/components/common/GreenButton.tsx +++ b/src/components/common/GreenButton.tsx @@ -17,7 +17,7 @@ const GreenButton: React.FC = ({ onClick={onClick} disabled={disabled} className={`w-[320px] h-[60px] rounded-[12px] font-bold py-4 text-title-sb-button font-semibold transition ${ - disabled ? 'bg-[#E6E6E6] text-[#919191]' : 'bg-[#65CE58] text-white' + disabled ? 'bg-disabled text-main-gray' : 'bg-main-color text-white' }`} > {text} diff --git a/src/components/common/LoginRequiredBottomSheet.tsx b/src/components/common/LoginRequiredBottomSheet.tsx index 22a52a6..0af6d1b 100644 --- a/src/components/common/LoginRequiredBottomSheet.tsx +++ b/src/components/common/LoginRequiredBottomSheet.tsx @@ -33,7 +33,7 @@ const LoginRequiredBottomSheet: React.FC = ({ 로그인이 필요한 기능이에요 {/* 서브텍스트 */} - + 로그인 후 더 많은 기능을 이용해볼까요? @@ -42,7 +42,7 @@ const LoginRequiredBottomSheet: React.FC = ({ {/* 버튼 영역 */} 취소하기 diff --git a/src/components/common/MenuBar.tsx b/src/components/common/MenuBar.tsx index ff44ff4..67a262f 100644 --- a/src/components/common/MenuBar.tsx +++ b/src/components/common/MenuBar.tsx @@ -101,7 +101,7 @@ const MenuBar = ({ isOpen, onClose }: MenuBarProps) => { {index === 4 && ( - + )} ))} diff --git a/src/components/common/Modal.tsx b/src/components/common/Modal.tsx index 29e78c6..eddb589 100644 --- a/src/components/common/Modal.tsx +++ b/src/components/common/Modal.tsx @@ -26,21 +26,21 @@ const Modal: React.FC = ({ {title} {description && ( - + {description} )} {cancelText} {confirmText} diff --git a/src/components/common/NoSearchResults.tsx b/src/components/common/NoSearchResults.tsx index 5f4e53e..ea94791 100644 --- a/src/components/common/NoSearchResults.tsx +++ b/src/components/common/NoSearchResults.tsx @@ -28,14 +28,14 @@ const NoSearchResults: React.FC = ({ {type === 'search' ? ( <> '{query}' - + 와 관련한 검색 결과가 없어요 > ) : ( <> - 내 주위에 가까운 - + 내 주위에 가까운 + 가맹점이 없어요 > @@ -45,7 +45,7 @@ const NoSearchResults: React.FC = ({ {/* 추천 검색어 영역 (추천 검색어가 있을 경우만 표시) */} {suggestedSearchTerm && ( onSuggestClick && onSuggestClick(suggestedSearchTerm)} > '{suggestedSearchTerm}'를 찾으셨나요? diff --git a/src/components/common/OptimizedImage.tsx b/src/components/common/OptimizedImage.tsx new file mode 100644 index 0000000..dd97627 --- /dev/null +++ b/src/components/common/OptimizedImage.tsx @@ -0,0 +1,47 @@ +import { useState } from "react"; + +interface OptimizedImageProps { + src: string; + alt: string; + className?: string; + width?: number; + height?: number; + priority?: boolean; // 첫 화면 LCP 이미지인 경우 true + onLoad?: () => void; // 이미지 로드 완료 콜백 +} + +export default function OptimizedImage({ + src, + alt, + className, + width, + height, + priority = false, + onLoad, +}: OptimizedImageProps) { + const [loaded, setLoaded] = useState(false); + + return ( + + { + setLoaded(true); + onLoad?.(); + }} + /> + {!loaded && } + + ); +} diff --git a/src/components/common/SearchInput.tsx b/src/components/common/SearchInput.tsx index 93e9caa..1acc88a 100644 --- a/src/components/common/SearchInput.tsx +++ b/src/components/common/SearchInput.tsx @@ -31,7 +31,7 @@ const SearchInput = ({ value={value} onChange={(e) => onChange(e.target.value)} onKeyDown={handleKeyDown} - className="flex-1 min-w-0 text-[#919191] text-[12px] tracking-[0.012px] focus:outline-none" + className="flex-1 min-w-0 text-main-gray text-[12px] tracking-[0.012px] focus:outline-none" /> diff --git a/src/components/common/Tag.tsx b/src/components/common/Tag.tsx index 500608b..bf19614 100644 --- a/src/components/common/Tag.tsx +++ b/src/components/common/Tag.tsx @@ -16,7 +16,7 @@ const Tag: React.FC = ({ label, selected = false, onClick, className = className={` flex-shrink-0 inline-flex w-fit items-center px-[16px] py-[6px] rounded-[12px] text-black - ${selected ? 'bg-[#B1D960] border border-[#B1D960]' : 'bg-[#F4F6F8] border border-[#919191]'} + ${selected ? 'bg-[#B1D960] border border-[#B1D960]' : 'bg-bg-gray border border-main-gray'} text-body-md-description ${className} `} diff --git a/src/components/common/TopBar.tsx b/src/components/common/TopBar.tsx index 90c67cf..1a7a2a7 100644 --- a/src/components/common/TopBar.tsx +++ b/src/components/common/TopBar.tsx @@ -82,7 +82,7 @@ export default function TopBar({ )} {subTitle && ( - + {subTitle} )} @@ -95,7 +95,7 @@ export default function TopBar({ )} {subTitle && ( - + {subTitle} )} diff --git a/src/components/common/WarningToast.tsx b/src/components/common/WarningToast.tsx index b905f46..1cd2ced 100644 --- a/src/components/common/WarningToast.tsx +++ b/src/components/common/WarningToast.tsx @@ -7,7 +7,7 @@ interface WarningToastProps { const WarningToast: React.FC = ({ text }) => { return ( - + {Array.isArray(text) ? ( diff --git a/src/components/convenience/ButtonGroup.tsx b/src/components/convenience/ButtonGroup.tsx index 0ee5e2a..c2ba386 100644 --- a/src/components/convenience/ButtonGroup.tsx +++ b/src/components/convenience/ButtonGroup.tsx @@ -18,8 +18,8 @@ export default function ButtonGroup({ key={option} onClick={() => onChange(selected === option ? '' : option)} className={` - px-4 py-1 rounded-[12px] border border-[#919191] text-[14px] font-regular leading-[24px] mb-[4px] - ${selected === option ? 'bg-[#B1D960] border-[#B1D960] text-black ' : 'bg-[#F4F6F8]'} + px-4 py-1 rounded-[12px] border border-main-gray text-[14px] font-regular leading-[24px] mb-[4px] + ${selected === option ? 'bg-[#B1D960] border-[#B1D960] text-black ' : 'bg-bg-gray'} `} > {option} diff --git a/src/components/convenience/CategoryFilterSelector.tsx b/src/components/convenience/CategoryFilterSelector.tsx index 50d6cd4..33d5de4 100644 --- a/src/components/convenience/CategoryFilterSelector.tsx +++ b/src/components/convenience/CategoryFilterSelector.tsx @@ -16,7 +16,7 @@ const CategoryFilterSelector: React.FC = ({ selected, onChange }) => { <> setOpen(true)} - className="flex items-center shrink-0 py-1 px-3 rounded-[12px] border border-[#919191] bg-[#F4F6F8] whitespace-nowrap text-[16px] font-medium leading-[24px] mb-[4px]" + className="flex items-center shrink-0 py-1 px-3 rounded-[12px] border border-main-gray bg-bg-gray whitespace-nowrap text-[16px] font-medium leading-[24px] mb-[4px]" > = ({ {!hideLabelText && ( - + {label} )} diff --git a/src/components/convenience/DeleteConvenience.tsx b/src/components/convenience/DeleteConvenience.tsx index ea17c98..1d4d0f0 100644 --- a/src/components/convenience/DeleteConvenience.tsx +++ b/src/components/convenience/DeleteConvenience.tsx @@ -19,19 +19,19 @@ export default function DeleteConvenienve({ 해당 글을 정말 삭제하시겠어요? - + 삭제된 글은 복구할 수 없어요 취소 삭제하기 diff --git a/src/components/convenience/FeedbackButtons.tsx b/src/components/convenience/FeedbackButtons.tsx index aa034b1..bbbe531 100644 --- a/src/components/convenience/FeedbackButtons.tsx +++ b/src/components/convenience/FeedbackButtons.tsx @@ -24,8 +24,8 @@ export default function FeedbackButtons({ isMine ? 'border-[#E0E0E0] text-[#C0C0C0] bg-[#F8F8F8] cursor-not-allowed' : userSelection === true - ? 'bg-[#B1D960] border-[#C3C3C3] text-[#616161]' - : 'bg-white hover:bg-[var(--BG,#F3F5ED)] border-[#C3C3C3] text-[#616161]' + ? 'bg-[#B1D960] border-sub-gray text-text-gray' + : 'bg-white hover:bg-[var(--BG,#F3F5ED)] border-sub-gray text-text-gray' }`} > 올바른 정보예요 @@ -38,8 +38,8 @@ export default function FeedbackButtons({ isMine ? 'border-[#E0E0E0] text-[#C0C0C0] bg-[#F8F8F8] cursor-not-allowed' : userSelection === false - ? 'bg-[#B1D960] border-[#C3C3C3] text-[#616161]' - : 'bg-white hover:bg-[var(--BG,#F3F5ED)] border-[#C3C3C3] text-[#616161]' + ? 'bg-[#B1D960] border-sub-gray text-text-gray' + : 'bg-white hover:bg-[var(--BG,#F3F5ED)] border-sub-gray text-text-gray' }`} > 잘못된 정보예요 diff --git a/src/components/convenience/ProductListSection.tsx b/src/components/convenience/ProductListSection.tsx index 83b0108..db9ebc1 100644 --- a/src/components/convenience/ProductListSection.tsx +++ b/src/components/convenience/ProductListSection.tsx @@ -108,7 +108,7 @@ export default function ProductListSection({ 아직은 공유된 제품 정보가 없어요 - + 여러분의 결제 경험을 공유해주세요 @@ -133,7 +133,7 @@ export default function ProductListSection({ if (suppressed) return; navigate(`/convenience/post/${p.id}`); }} - className="flex justify-between items-center py-[14px] border-b-[3px] border-[#F4F6F8] cursor-pointer" + className="flex justify-between items-center py-[14px] border-b-[3px] border-bg-gray cursor-pointer" > {/* 왼쪽: 이름(애니메이션) + 시간(고정) */} @@ -153,7 +153,7 @@ export default function ProductListSection({ - + {p.relativeCreatedAt} @@ -168,10 +168,10 @@ export default function ProductListSection({ animate="center" exit="exit" custom={dir} - className={`inline-block text-[12px] leading-[18px] font-semibold tracking-[0.01em] bg-[#F4F6F8] border-[1px] rounded-[8px] px-3 py-1 will-change-transform ${ + className={`inline-block text-[12px] leading-[18px] font-semibold tracking-[0.01em] bg-bg-gray border-[1px] rounded-[8px] px-3 py-1 will-change-transform ${ p.isAvailable - ? 'text-[#029F64] border-[#029F64]' - : 'text-[#FF6452] border-[#FF6452]' + ? 'text-sub-color border-main-color' + : 'text-warning border-warning' }`} > {p.isAvailable ? '결제가능' : '결제불가'} diff --git a/src/components/convenience/SelectableButton.tsx b/src/components/convenience/SelectableButton.tsx index e6d4df2..5703267 100644 --- a/src/components/convenience/SelectableButton.tsx +++ b/src/components/convenience/SelectableButton.tsx @@ -23,7 +23,7 @@ export default function SelectableButton({ ${ isSelected ? `bg-[${selectedBgColor}] border-[${selectedBorderColor}] text-black` - : 'bg-white hover:bg-[var(--BG,#F3F5ED)] border-[#C3C3C3] text-[#616161]' + : 'bg-white hover:bg-[var(--BG,#F3F5ED)] border-sub-gray text-text-gray' } ${className} `} diff --git a/src/components/home/CarouselBanner.tsx b/src/components/home/CarouselBanner.tsx index 8f56bde..452d147 100644 --- a/src/components/home/CarouselBanner.tsx +++ b/src/components/home/CarouselBanner.tsx @@ -20,7 +20,7 @@ export default function CarouselBanner({ onSlideChange }: CarouselBannerProps) { content: ( - 아동급식카드 + 아동급식카드 사용 가맹점을 검색하고, 리뷰를 남겨보세요! @@ -31,10 +31,10 @@ export default function CarouselBanner({ onSlideChange }: CarouselBannerProps) { { content: ( - + 현재는{' '} - + 인천, 부천, 수원, 고양, 용인, 성남 만 제공되며,{' '} @@ -43,7 +43,7 @@ export default function CarouselBanner({ onSlideChange }: CarouselBannerProps) { navigate('/feedback', { state: { returnTo: '/' } })} > @@ -80,7 +80,7 @@ export default function CarouselBanner({ onSlideChange }: CarouselBannerProps) { ))} diff --git a/src/components/home/CategorySection.tsx b/src/components/home/CategorySection.tsx index f85decf..9d56ed4 100644 --- a/src/components/home/CategorySection.tsx +++ b/src/components/home/CategorySection.tsx @@ -12,7 +12,7 @@ function CategorySection() { const mainCategories = categories.slice(1, -1); return ( - + {mainCategories.map((category) => ( 확인하러 가기 diff --git a/src/components/home/ConvenienceStoreSection.tsx b/src/components/home/ConvenienceStoreSection.tsx index 685254f..53722bb 100644 --- a/src/components/home/ConvenienceStoreSection.tsx +++ b/src/components/home/ConvenienceStoreSection.tsx @@ -55,7 +55,7 @@ function ConvenienceStoreSection() { }, [selectedBrand]); return ( - + @@ -80,7 +80,7 @@ function ConvenienceStoreSection() { {noResult ? '정보 공유하기' : '전체보기'} @@ -89,10 +89,10 @@ function ConvenienceStoreSection() { {noResult ? ( - + 아직은 공유된 제품 정보가 없어요 - + 여러분의 결제 경험을 공유해주세요 @@ -106,10 +106,10 @@ function ConvenienceStoreSection() { > {item.name} {item.isAvailable ? '결제가능' : '결제불가'} @@ -117,7 +117,7 @@ function ConvenienceStoreSection() { {/* {item.isAvailable ? '결제가능' : '결제불가'} diff --git a/src/components/home/HomeTopBar.tsx b/src/components/home/HomeTopBar.tsx index c02d739..9114f69 100644 --- a/src/components/home/HomeTopBar.tsx +++ b/src/components/home/HomeTopBar.tsx @@ -45,7 +45,7 @@ export default function HomeTopBar({ address = '' }: HomeTopBarProps) { - + {address} @@ -58,7 +58,7 @@ export default function HomeTopBar({ address = '' }: HomeTopBarProps) { ) : ( 로그인하기 diff --git a/src/components/home/Top8StoreSection.tsx b/src/components/home/Top8StoreSection.tsx index b9ed4c4..f65c590 100644 --- a/src/components/home/Top8StoreSection.tsx +++ b/src/components/home/Top8StoreSection.tsx @@ -19,7 +19,7 @@ function Top8StoreSection() { }; return ( - + 오늘 끼니는 여기 어때요? diff --git a/src/components/home/TopStoreItem.tsx b/src/components/home/TopStoreItem.tsx index 790d8b2..e0dcbf6 100644 --- a/src/components/home/TopStoreItem.tsx +++ b/src/components/home/TopStoreItem.tsx @@ -71,7 +71,7 @@ const TopStoreItem = ({ store }: TopStoreItemProps) => { {/* 주소: 이름이 2줄이면 1줄, 1줄이면 2줄 */} @@ -79,7 +79,7 @@ const TopStoreItem = ({ store }: TopStoreItemProps) => { {/* 조회수 */} - + 조회 {store.viewCount} diff --git a/src/components/notification/EmptyNotification.tsx b/src/components/notification/EmptyNotification.tsx index db7d2b8..d75bc10 100644 --- a/src/components/notification/EmptyNotification.tsx +++ b/src/components/notification/EmptyNotification.tsx @@ -2,7 +2,7 @@ import EmptyIcon from '@/assets/svgs/logo/curious-congG.svg'; export default function EmptyNotification() { return ( - + {createdAt} - + {senderNickname} - + 님이 {content} diff --git a/src/pages/auth/MyNeighborhoodPage.tsx b/src/pages/auth/MyNeighborhoodPage.tsx index 65de358..e98ae0c 100644 --- a/src/pages/auth/MyNeighborhoodPage.tsx +++ b/src/pages/auth/MyNeighborhoodPage.tsx @@ -120,14 +120,14 @@ function MyNeighborhoodPage() { /> 자주 가는 지역을 - 즐겨찾는 지역으로 등록할 수 있어요 + 즐겨찾는 지역으로 등록할 수 있어요 - + 자주 가는 지역을 설정하면 매번 GPS를 허용하지 않아도 빠르게 확인할 수 있어요. - - 현재는 인천,부천,수원,고양,용인,성남시만 제공되며, + + 현재는 인천,부천,수원,고양,용인,성남시만 제공되며, 다른 지역은 요청이 많은 순으로 추가될 예정이에요. @@ -135,17 +135,17 @@ function MyNeighborhoodPage() { - + {dongList && dongList.length > 0 ? ( - + {dongList.map((dong:any) => ( ) : city && district && !selectedDong ? ( - + *해당하는 지역이 없어요 ) : null} diff --git a/src/pages/auth/NicknamePage.tsx b/src/pages/auth/NicknamePage.tsx index a9a0965..7e5972f 100644 --- a/src/pages/auth/NicknamePage.tsx +++ b/src/pages/auth/NicknamePage.tsx @@ -90,7 +90,7 @@ export default function NicknamePage() { 반가워요! - + 사용할 닉네임을 정해주세요 @@ -131,7 +131,7 @@ export default function NicknamePage() { {/* 하단 고정 버튼 */} - + 끼니콩에 가입함으로써 끼니콩의{' '} @@ -142,7 +142,7 @@ export default function NicknamePage() { '_blank', ) } - className="text-[#919191] font-pretendard text-[12px] font-bold leading-[150%] tracking-[0.012px] underline decoration-solid underline-offset-2 decoration-auto" + className="text-main-gray font-pretendard text-[12px] font-bold leading-[150%] tracking-[0.012px] underline decoration-solid underline-offset-2 decoration-auto" > 이용 약관 diff --git a/src/pages/auth/NicknamePageXXX.tsx b/src/pages/auth/NicknamePageXXX.tsx index 1d4e772..e9e8ff2 100644 --- a/src/pages/auth/NicknamePageXXX.tsx +++ b/src/pages/auth/NicknamePageXXX.tsx @@ -9,11 +9,11 @@ function NicknamePageXXX() { 반가워요! - + 사용할 닉네임을 정해주세요 - + 설정한 닉네임은 마이페이지에서 수정할 수 있어요 diff --git a/src/pages/community/CommunityPostDetailPage.tsx b/src/pages/community/CommunityPostDetailPage.tsx index 4602a9f..489cc70 100644 --- a/src/pages/community/CommunityPostDetailPage.tsx +++ b/src/pages/community/CommunityPostDetailPage.tsx @@ -17,6 +17,7 @@ import useCommentActions from '@/hooks/useCommentActions'; import DeleteModal from '@/components/common/DeleteModal'; import ConfirmToast from '@/components/common/ConfirmToast'; import { createPortal } from 'react-dom'; +import OptimizedImage from '@/components/common/OptimizedImage'; interface Comment { commentId: number; @@ -209,7 +210,7 @@ const CommunityPostDetailPage = () => { showBackButton={true} onBack={() => navigate('/community')} /> - + @@ -233,7 +234,7 @@ const CommunityPostDetailPage = () => { {post.nickname ?? '익명'} - + {post.isModified && '수정됨 ·'}{post.createdAt} · 조회 {post.viewCount} @@ -252,7 +253,7 @@ const CommunityPostDetailPage = () => { {Array.isArray(post.imageUrls) && post.imageUrls.length > 0 && ( {post.imageUrls.map((url, idx) => ( - { - + @@ -294,7 +295,7 @@ const CommunityPostDetailPage = () => { /> {/*댓글*/} - + {post.commentCount} diff --git a/src/pages/community/CommunityWritePage.tsx b/src/pages/community/CommunityWritePage.tsx index cf65bd7..dd1eb3d 100644 --- a/src/pages/community/CommunityWritePage.tsx +++ b/src/pages/community/CommunityWritePage.tsx @@ -136,7 +136,7 @@ export default function CommunityWritePage() { placeholder="글 제목" value={title} onChange={(e) => setTitle(e.target.value)} - className="w-full border-[1px] border-[#C3C3C3] rounded-[12px] px-4 py-3 text-body-md-description fort-reular placeholder:text-[#919191]" + className="w-full border-[1px] border-sub-gray rounded-[12px] px-4 py-3 text-body-md-description fort-reular placeholder:text-main-gray" /> @@ -151,7 +151,7 @@ export default function CommunityWritePage() { el.style.height = 'auto'; // 높이 초기화 el.style.height = `${el.scrollHeight}px`; // 내용에 맞게 확장 }} - className="w-full border-[1px] border-[#C3C3C3] rounded-[12px] px-4 py-3 h-[70px] text-body-md-description fort-reular placeholder:text-[#919191] resize-none scrollbar-hide" + className="w-full border-[1px] border-sub-gray rounded-[12px] px-4 py-3 h-[70px] text-body-md-description fort-reular placeholder:text-main-gray resize-none scrollbar-hide" /> @@ -159,7 +159,7 @@ export default function CommunityWritePage() { 사진을 추가해주세요 - (선택/최대 3장) + (선택/최대 3장) @@ -168,8 +168,8 @@ export default function CommunityWritePage() { 등록하기 diff --git a/src/pages/convenience/AddConveniencePage.tsx b/src/pages/convenience/AddConveniencePage.tsx index dd8762c..5e9d017 100644 --- a/src/pages/convenience/AddConveniencePage.tsx +++ b/src/pages/convenience/AddConveniencePage.tsx @@ -85,11 +85,11 @@ export default function AddConveniencePage() { value={productName} onChange={(e) => setProductName(e.target.value)} placeholder="ex) 서울우유 500ML" - className="w-full p-4 border border-[#C3C3C3] rounded-[12px] text-[#616161] text-body-md-title - placeholder:text-[#919191] placeholder:text-body-md-description" + className="w-full p-4 border border-sub-gray rounded-[12px] text-text-gray text-body-md-title + placeholder:text-main-gray placeholder:text-body-md-description" /> navigate('/convenience/name-recommendation')} > 상세설명 (선택) - + {description.length}/300 @@ -134,8 +134,8 @@ export default function AddConveniencePage() { onChange={(e) => setDescription(e.target.value)} maxLength={300} placeholder="ex) 직원이 알려줬어요" - className="w-full p-4 border border-[#C3C3C3] rounded-[12px] text-[#616161] text-body-md-title - placeholder:text-[#919191] placeholder:text-body-md-description" + className="w-full p-4 border border-sub-gray rounded-[12px] text-text-gray text-body-md-title + placeholder:text-main-gray placeholder:text-body-md-description" /> @@ -156,10 +156,10 @@ export default function AddConveniencePage() { {post.userNickname} - + {post.createTime} @@ -182,10 +182,10 @@ export default function ConvenienceDetailPage() { {/* 상품명 , 상태, 카테고리 */} {post.isAvailable ? '결제가능' : '결제불가'} @@ -194,10 +194,10 @@ export default function ConvenienceDetailPage() { {post.name} - + {fromServerCategory(post.category)} - + {fromServerBrand(post.brand)} @@ -209,13 +209,13 @@ export default function ConvenienceDetailPage() { 상세설명 - + {post.description} {/* 구분선 */} - + {/* 피드백 버튼 */} 제품명 - + setKeyword(e.target.value)} placeholder="ex) 서울우유 500ML" - className="flex-1 outline-none text-[#616161] text-body-md-title - placeholder:text-[#919191] placeholder:text-body-md-description" + className="flex-1 outline-none text-text-gray text-body-md-title + placeholder:text-main-gray placeholder:text-body-md-description" /> @@ -101,7 +101,7 @@ export default function NameRecommendationPage() { } }} className={`mt-auto mb-6 mx-4 py-3 rounded-[12px] font-semibold text-white ${ - selected ? 'bg-[#65CE58]' : 'bg-[#E6E6E6]' + selected ? 'bg-main-color' : 'bg-disabled' }`} disabled={!selected} > diff --git a/src/pages/home/HomePage.tsx b/src/pages/home/HomePage.tsx index db16b0c..a02ae55 100644 --- a/src/pages/home/HomePage.tsx +++ b/src/pages/home/HomePage.tsx @@ -1,4 +1,4 @@ -import { Helmet } from 'react-helmet-async'; + import HeaderToCarouselSection from '@/components/home/HeaderToCarouselSection'; import CategorySection from '@/components/home/CategorySection'; diff --git a/src/pages/mypage/AccountDeletePage.tsx b/src/pages/mypage/AccountDeletePage.tsx index ae8c980..0c21547 100644 --- a/src/pages/mypage/AccountDeletePage.tsx +++ b/src/pages/mypage/AccountDeletePage.tsx @@ -35,32 +35,32 @@ const AccountDeletePage = () => { - + 탈퇴 처리 안내 탈퇴한 아이디는 본인과 타인 모두{' '} - 재사용 및 복구가 불가 + 재사용 및 복구가 불가 하오니 신중하게 선택하시기 바랍니다. 탈퇴 후{' '} - 회원정보는 모두 삭제 + 회원정보는 모두 삭제 됩니다. - + 개인정보 삭제 안내 - + 탈퇴 후에도{' '} - 등록한 게시물은 그대로{' '} + 등록한 게시물은 그대로{' '} 남아 있습니다. [편의점 정보 공유 게시판]과 [커뮤니티]에 올린 게시글 및 댓글은 탈퇴 시 자동 삭제되지 않고 그대로 남아 있으며, 작성자 정보는 비식별화 처리됩니다. 삭제를 원하는 게시글이 있다면 반드시{' '} - + 탈퇴 전 비공개 처리하거나 삭제 하시기 바랍니다. @@ -83,7 +83,7 @@ const AccountDeletePage = () => { 위 사항을 모두 확인하였으며, 이에 동의합니다. diff --git a/src/pages/mypage/FeedbackPage.tsx b/src/pages/mypage/FeedbackPage.tsx index 684b767..9d86563 100644 --- a/src/pages/mypage/FeedbackPage.tsx +++ b/src/pages/mypage/FeedbackPage.tsx @@ -45,7 +45,7 @@ const FeedbackPage = () => { /> - + 끼니콩을 이용하면서 diff --git a/src/pages/mypage/MyLikesPage.tsx b/src/pages/mypage/MyLikesPage.tsx index b162a85..ae39490 100644 --- a/src/pages/mypage/MyLikesPage.tsx +++ b/src/pages/mypage/MyLikesPage.tsx @@ -73,12 +73,12 @@ const MyLikesPage = () => { /> {loading && totalCount === 0 ? null : totalCount === 0 ? ( - + ) : ( - + 좋아요 한 글 {totalCount}개 diff --git a/src/pages/mypage/MyPostsPage.tsx b/src/pages/mypage/MyPostsPage.tsx index f087462..b85bbcc 100644 --- a/src/pages/mypage/MyPostsPage.tsx +++ b/src/pages/mypage/MyPostsPage.tsx @@ -83,11 +83,11 @@ const MyPostsPage = () => { onChange={handleChipChange} className={ tab === '게시글' && chip === '커뮤니티' && isCommunityEmpty - ? 'bg-[#F4F6F8]' + ? 'bg-bg-gray' : tab === '게시글' && chip === '편의점 게시판' && isConvenienceEmpty - ? 'bg-[#F4F6F8]' + ? 'bg-bg-gray' : '' } /> diff --git a/src/pages/mypage/MyReviewsPage.tsx b/src/pages/mypage/MyReviewsPage.tsx index fc85586..cd16682 100644 --- a/src/pages/mypage/MyReviewsPage.tsx +++ b/src/pages/mypage/MyReviewsPage.tsx @@ -89,12 +89,12 @@ const MyReviewsPage = () => { onBack={() => navigate('/mypage')} /> {totalCount === 0 ? ( - + ) : ( - + 내가 쓴 리뷰 수 {totalCount}개 diff --git a/src/pages/mypage/MyScrapPage.tsx b/src/pages/mypage/MyScrapPage.tsx index c31df67..92f6d5e 100644 --- a/src/pages/mypage/MyScrapPage.tsx +++ b/src/pages/mypage/MyScrapPage.tsx @@ -61,7 +61,7 @@ const MyScrapPage = () => { /> {loading ? null : scrapStores.length === 0 ? ( - + { ) : ( - + 내가 찜한 가게 수 {scrapStores.length}개 { 수정할 닉네임을 적어주세요 - + 닉네임 수정은 1회 가능해요 diff --git a/src/pages/store-review/StoreReviewPage.tsx b/src/pages/store-review/StoreReviewPage.tsx index 5aecb82..d6e54f0 100644 --- a/src/pages/store-review/StoreReviewPage.tsx +++ b/src/pages/store-review/StoreReviewPage.tsx @@ -108,8 +108,8 @@ const StoreReviewPage = () => { disabled={!isSubmitEnabled} className={`text-white font-semibold text-title-sb-button px-[16px] py-[12px] rounded-[8px] mt-[24px] ${ isSubmitEnabled - ? 'bg-[#65CE58]' - : 'bg-[#E6E6E6] cursor-not-allowed' + ? 'bg-main-color' + : 'bg-disabled cursor-not-allowed' }`} > 공유하기 diff --git a/tailwind.config.ts b/tailwind.config.ts index 129c583..d63a621 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -15,7 +15,17 @@ const config: Config = { pretendard: ['Pretendard', 'sans-serif'], }, colors: { + + black: '#212121', 'main-color': '#65CE58', + 'sub-color': '#029F64', + 'disabled': '#E6E6E6', + 'warning': '#FF6452', + 'main-gray': '#919191', + 'sub-gray': '#C3C3C3', + 'bg-gray': '#F4F6F8', + 'text-gray': '#616161', + 'bg': 'rgba(243, 245, 237, 1)', }, boxShadow: { custom: '2px 4px 10px 0px rgba(0, 0, 0, 0.20)', diff --git a/vite.config.ts b/vite.config.ts index 83eb9fe..0e97368 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -2,10 +2,36 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import svgr from 'vite-plugin-svgr'; import path from 'path'; +import { visualizer } from 'rollup-plugin-visualizer'; export default defineConfig({ plugins: [react(), svgr()], resolve: { alias: [{ find: '@', replacement: path.resolve(__dirname, 'src') }], }, + build: { + target: 'es2020', + minify: 'terser', + terserOptions: { + compress: { + drop_console: true, + drop_debugger: true, + }, + }, + rollupOptions: { + output: { + manualChunks: { + vendor: ['react', 'react-dom'], + router: ['react-router-dom'], + swiper: ['swiper/react', 'swiper/modules'], + }, + }, + }, + }, + optimizeDeps: { + include: ['react', 'react-dom', 'react-router-dom'], + }, + esbuild: { + drop: ['console', 'debugger'], + }, });
{question}
보내주신 의견은 운영팀이 검토 후 반영됩니다
{line}
{title}
{description}
글쓰기
검색 결과가 없어요
가맹점이 없어요
해당 글을 정말 삭제하시겠어요?
삭제된 글은 복구할 수 없어요
아직은 공유된 제품 정보가 없어요
여러분의 결제 경험을 공유해주세요
아동급식카드
사용 가맹점을 검색하고,
리뷰를 남겨보세요!
오늘 끼니는 여기 어때요?
{createdAt}
님이 {content}
자주 가는 지역을
즐겨찾는 지역으로 등록할 수 있어요
*해당하는 지역이 없어요
사용할 닉네임을 정해주세요
끼니콩에 가입함으로써 끼니콩의{' '} @@ -142,7 +142,7 @@ export default function NicknamePage() { '_blank', ) } - className="text-[#919191] font-pretendard text-[12px] font-bold leading-[150%] tracking-[0.012px] underline decoration-solid underline-offset-2 decoration-auto" + className="text-main-gray font-pretendard text-[12px] font-bold leading-[150%] tracking-[0.012px] underline decoration-solid underline-offset-2 decoration-auto" > 이용 약관 diff --git a/src/pages/auth/NicknamePageXXX.tsx b/src/pages/auth/NicknamePageXXX.tsx index 1d4e772..e9e8ff2 100644 --- a/src/pages/auth/NicknamePageXXX.tsx +++ b/src/pages/auth/NicknamePageXXX.tsx @@ -9,11 +9,11 @@ function NicknamePageXXX() {
설정한 닉네임은 마이페이지에서 수정할 수 있어요
{post.description}
탈퇴 처리 안내
개인정보 삭제 안내
탈퇴 후에도{' '} - 등록한 게시물은 그대로{' '} + 등록한 게시물은 그대로{' '} 남아 있습니다. [편의점 정보 공유 게시판]과 [커뮤니티]에 올린 게시글 및 댓글은 탈퇴 시 자동 삭제되지 않고 그대로 남아 있으며, 작성자 정보는 비식별화 처리됩니다. 삭제를 원하는 게시글이 있다면 반드시{' '} - + 탈퇴 전 비공개 처리하거나 삭제 하시기 바랍니다. @@ -83,7 +83,7 @@ const AccountDeletePage = () => { 위 사항을 모두 확인하였으며, 이에 동의합니다. diff --git a/src/pages/mypage/FeedbackPage.tsx b/src/pages/mypage/FeedbackPage.tsx index 684b767..9d86563 100644 --- a/src/pages/mypage/FeedbackPage.tsx +++ b/src/pages/mypage/FeedbackPage.tsx @@ -45,7 +45,7 @@ const FeedbackPage = () => { /> - + 끼니콩을 이용하면서 diff --git a/src/pages/mypage/MyLikesPage.tsx b/src/pages/mypage/MyLikesPage.tsx index b162a85..ae39490 100644 --- a/src/pages/mypage/MyLikesPage.tsx +++ b/src/pages/mypage/MyLikesPage.tsx @@ -73,12 +73,12 @@ const MyLikesPage = () => { /> {loading && totalCount === 0 ? null : totalCount === 0 ? ( - + ) : ( - + 좋아요 한 글 {totalCount}개 diff --git a/src/pages/mypage/MyPostsPage.tsx b/src/pages/mypage/MyPostsPage.tsx index f087462..b85bbcc 100644 --- a/src/pages/mypage/MyPostsPage.tsx +++ b/src/pages/mypage/MyPostsPage.tsx @@ -83,11 +83,11 @@ const MyPostsPage = () => { onChange={handleChipChange} className={ tab === '게시글' && chip === '커뮤니티' && isCommunityEmpty - ? 'bg-[#F4F6F8]' + ? 'bg-bg-gray' : tab === '게시글' && chip === '편의점 게시판' && isConvenienceEmpty - ? 'bg-[#F4F6F8]' + ? 'bg-bg-gray' : '' } /> diff --git a/src/pages/mypage/MyReviewsPage.tsx b/src/pages/mypage/MyReviewsPage.tsx index fc85586..cd16682 100644 --- a/src/pages/mypage/MyReviewsPage.tsx +++ b/src/pages/mypage/MyReviewsPage.tsx @@ -89,12 +89,12 @@ const MyReviewsPage = () => { onBack={() => navigate('/mypage')} /> {totalCount === 0 ? ( - + ) : ( - + 내가 쓴 리뷰 수 {totalCount}개 diff --git a/src/pages/mypage/MyScrapPage.tsx b/src/pages/mypage/MyScrapPage.tsx index c31df67..92f6d5e 100644 --- a/src/pages/mypage/MyScrapPage.tsx +++ b/src/pages/mypage/MyScrapPage.tsx @@ -61,7 +61,7 @@ const MyScrapPage = () => { /> {loading ? null : scrapStores.length === 0 ? ( - + { ) : ( - + 내가 찜한 가게 수 {scrapStores.length}개 { 수정할 닉네임을 적어주세요 - + 닉네임 수정은 1회 가능해요 diff --git a/src/pages/store-review/StoreReviewPage.tsx b/src/pages/store-review/StoreReviewPage.tsx index 5aecb82..d6e54f0 100644 --- a/src/pages/store-review/StoreReviewPage.tsx +++ b/src/pages/store-review/StoreReviewPage.tsx @@ -108,8 +108,8 @@ const StoreReviewPage = () => { disabled={!isSubmitEnabled} className={`text-white font-semibold text-title-sb-button px-[16px] py-[12px] rounded-[8px] mt-[24px] ${ isSubmitEnabled - ? 'bg-[#65CE58]' - : 'bg-[#E6E6E6] cursor-not-allowed' + ? 'bg-main-color' + : 'bg-disabled cursor-not-allowed' }`} > 공유하기 diff --git a/tailwind.config.ts b/tailwind.config.ts index 129c583..d63a621 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -15,7 +15,17 @@ const config: Config = { pretendard: ['Pretendard', 'sans-serif'], }, colors: { + + black: '#212121', 'main-color': '#65CE58', + 'sub-color': '#029F64', + 'disabled': '#E6E6E6', + 'warning': '#FF6452', + 'main-gray': '#919191', + 'sub-gray': '#C3C3C3', + 'bg-gray': '#F4F6F8', + 'text-gray': '#616161', + 'bg': 'rgba(243, 245, 237, 1)', }, boxShadow: { custom: '2px 4px 10px 0px rgba(0, 0, 0, 0.20)', diff --git a/vite.config.ts b/vite.config.ts index 83eb9fe..0e97368 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -2,10 +2,36 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import svgr from 'vite-plugin-svgr'; import path from 'path'; +import { visualizer } from 'rollup-plugin-visualizer'; export default defineConfig({ plugins: [react(), svgr()], resolve: { alias: [{ find: '@', replacement: path.resolve(__dirname, 'src') }], }, + build: { + target: 'es2020', + minify: 'terser', + terserOptions: { + compress: { + drop_console: true, + drop_debugger: true, + }, + }, + rollupOptions: { + output: { + manualChunks: { + vendor: ['react', 'react-dom'], + router: ['react-router-dom'], + swiper: ['swiper/react', 'swiper/modules'], + }, + }, + }, + }, + optimizeDeps: { + include: ['react', 'react-dom', 'react-router-dom'], + }, + esbuild: { + drop: ['console', 'debugger'], + }, });
끼니콩을 이용하면서 diff --git a/src/pages/mypage/MyLikesPage.tsx b/src/pages/mypage/MyLikesPage.tsx index b162a85..ae39490 100644 --- a/src/pages/mypage/MyLikesPage.tsx +++ b/src/pages/mypage/MyLikesPage.tsx @@ -73,12 +73,12 @@ const MyLikesPage = () => { /> {loading && totalCount === 0 ? null : totalCount === 0 ? ( -
수정할 닉네임을 적어주세요
닉네임 수정은 1회 가능해요