Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions src/assets/svgs/modal/errorIcon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/components/common/ToastModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const ToastModal = ({

<div className="relative flex items-center bg-white px-4 py-3 rounded-xl shadow-[0_2px_10px_rgba(0,0,0,0.08)] min-w-[240px] max-w-[90vw]">
<IconComponent className="w-6 h-6 mr-3" />
<span className="text-b1 text-gray-12 font-semibold whitespace-nowrap">
<span className="text-b1 text-gray-12 b4 whitespace-pre-line">
{message}
</span>
</div>
Expand Down
18 changes: 0 additions & 18 deletions src/constants/review/reviewData.js

This file was deleted.

19 changes: 5 additions & 14 deletions src/pages/map/components/review/ConfirmImage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,12 @@ import { formatDateTime } from "@/pages/map/utils/formatDateTime";
import { usePaymentStore } from "@/store/paymentStore";
import { getDistanceDiff } from "@/pages/map/utils/getDistanceDiff";
import { formatToYMDHMS } from "@/store/paymentStore";
import { businessTypeNameMap } from "@/constants/categoryMap";

const ConfirmImage = ({ onReject, data, onConfirmComplete }) => {
const navigate = useNavigate();
// 이 화면에서 넘겨야 할 것 -> 시간 정보, 결제승인번호
const setReviewInfo = usePaymentStore((s) => s.setReviewInfo);
const { companyId } = usePaymentStore();

const moveToReviewPage = () => {
onConfirmComplete?.();
};

// const handleClick = () => {
// const newDate = new Date(/* year, month-1, day, hour, minute */);
// setPaymentTime(newDate);

// navigate("/writereview");
// };
const setReviewInfo = usePaymentStore((s) => s.setReviewInfo);

const handleClick = () => {
const pad = (n) => String(n).padStart(2, "0");
Expand Down Expand Up @@ -241,7 +230,9 @@ const ConfirmImage = ({ onReject, data, onConfirmComplete }) => {
<div className="w-80 h-24 bg-gray-2 px-5 py-4 flex flex-col gap-2 mt-2 sm:w-[77%]">
<div className="flex gap-2 justify-start items-center">
<p className="h3 text-gray-12">{data?.storeName}</p>
<p className="b4 text-gray-6">{data?.companyCategory ?? "기타"}</p>
<p className="b4 text-gray-6">
{businessTypeNameMap[data?.companyCategory] ?? "기타"}
</p>
</div>
<div className="flex gap-2 justify-start items-center">
<p className="b4 text-gray-12">
Expand Down
37 changes: 28 additions & 9 deletions src/pages/map/components/review/ReviewImageCapture.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { useState, useRef, useEffect } from "react";
import { useMutation } from "@tanstack/react-query";
import { postRecipt } from "@/apis/review/postRecipt";
import { useNavigate } from "react-router-dom";
import Modal from "@/pages/map/components/Modal";
import ReceiptErrorModal from "@/pages/map/components/review/ReceiptErrorModal";
import "@/styles/spinner.css";

import { usePaymentStore } from "@/store/paymentStore";
import ErrorIcon from "/public/svgs/modal/errorIcon.svg?react";
import ToastModal from "@/components/common/ToastModal";

import imageCompression from "browser-image-compression";
const ReviewImageCapture = ({
Expand All @@ -15,8 +14,6 @@ const ReviewImageCapture = ({
onCloseCamera,
onCaptureSuccess,
}) => {
const navigate = useNavigate();

useEffect(() => () => stopCamera(), []);

const streamRef = useRef(null);
Expand All @@ -33,6 +30,17 @@ const ReviewImageCapture = ({
const [showIntroModal, setShowIntroModal] = useState(false);
const [showReceiptError, setShowReceiptError] = useState(false);

// 1) 토스트 상태 & 실행 함수
const [toast, setToast] = useState({
show: false,
message: "",
icon: null,
});
const fireToast = (message, icon = ErrorIcon, duration = 4000) => {
setToast({ show: true, message, icon });
setTimeout(() => setToast((t) => ({ ...t, show: false })), duration);
};

useEffect(() => {
const hasSeenModal = localStorage.getItem("hasSeenCameraIntro");

Expand All @@ -55,7 +63,10 @@ const ReviewImageCapture = ({
}
} catch (error) {
console.log("카메라 접근 실패", error);
alert("카메라 접근에 실패했습니다. 카메라 접근 권한을 확인해 주세요!");
fireToast(
"카메라 접근에 실패했습니다.\n카메라 권한을 확인해 주세요!",
ErrorIcon
);
}
};

Expand Down Expand Up @@ -101,7 +112,7 @@ const ReviewImageCapture = ({
const file = e.target.files?.[0];
if (file) {
if (!file.type.startsWith("image/")) {
alert("이미지 파일만 선택 가능합니다.");
fireToast("이미지 파일만 선택 가능합니다.", ErrorIcon);
e.target.value = "";
fileInputRef.current?.click();
return;
Expand Down Expand Up @@ -170,13 +181,13 @@ const ReviewImageCapture = ({
// FormData 에 file + companyId 담기
const form = new FormData();
form.append("file", compressedFile, compressedFile.name);
form.append("companyId", String(780));
form.append("companyId", String(companyId));

// 단일 인자로 FormData 전달
mutate(form);
} catch (e) {
console.error(e);
alert("이미지 압축 실패");
fireToast("이미지 압축에 실패했습니다. 다시 시도해 주세요!", ErrorIcon);
}
};

Expand All @@ -186,6 +197,14 @@ const ReviewImageCapture = ({
onTouchStart={(e) => e.stopPropagation()}
onTouchEnd={(e) => e.stopPropagation()}
>
{toast.show && (
<ToastModal
message={toast.message}
icon={toast.icon}
duration={2000}
onClose={() => setToast((t) => ({ ...t, show: false }))}
/>
)}
<div>
{/* 숨겨진 input */}
<input
Expand Down
1 change: 0 additions & 1 deletion src/pages/map/components/review/ReviewList.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useState } from "react";
import { reviewData } from "@/constants/review/reviewData";
import ReviewContent from "@/pages/map/components/review/ReviewContent";
import { Link, useNavigate } from "react-router-dom";
import { useGetStoreReviewCount, useStoreReviews } from "@/apis/review/queries";
Expand Down
35 changes: 24 additions & 11 deletions src/pages/myPage/MyPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { useGetLikeCountOfMember } from "@/apis/member/queries";
import api from "@/apis/instance/api";
import { useNavigate } from "react-router-dom";
import useAuthStore from "@/store/authStore";
import ErrorIcon from "/public/svgs/modal/errorIcon.svg?react";
import ToastModal from "@/components/common/ToastModal";

const LogoutSuccessModal = ({ onClose }) => (
<div className="fixed inset-0 z-[10001] flex justify-center items-center bg-black bg-opacity-30">
Expand All @@ -33,6 +35,16 @@ const MyPage = () => {
const [showLogoutModal, setShowLogoutModal] = useState(false);
const { logout: setLoggedOut, isLogout } = useAuthStore();

const [toast, setToast] = useState({
show: false,
message: "",
icon: null,
});
const fireToast = (message, icon = ErrorIcon, duration = 4000) => {
setToast({ show: true, message, icon });
setTimeout(() => setToast((t) => ({ ...t, show: false })), duration);
};

const nickname = data?.name ?? "";
const location = data?.address ?? "";
const counts = {
Expand All @@ -53,13 +65,14 @@ const MyPage = () => {
setLoggedOut();
setShowLogoutModal(true);
} catch (e) {
alert("로그아웃에 실패하였습니다.");
fireToast("로그아웃에 실패하였습니다.", ErrorIcon);
}
};

if (isLoading) {
return (
<div className="min-h-screen flex justify-center items-center">
<p>로딩 중…</p>
<p className="b4">로딩 중…</p>
</div>
);
}
Expand All @@ -78,15 +91,6 @@ const MyPage = () => {

return (
<div className="min-h-screen bg-gray-2 flex flex-col items-center pt-32 relative p-5">
{/* {showLoginModal && (
<HaveToLoginModal
message="로그인이 필요한 서비스입니다"
subMessage=""
showButton={true}
showClose={false} // 닫기 아이콘 숨기기
onClose={() => {}} // 내부 close는 더 이상 호출되지 않음
/>
)} */}
{/* 로그아웃 완료 모달 */}
{showLogoutModal && <LogoutSuccessModal onClose={() => navigate("/")} />}
{/* 카드 */}
Expand Down Expand Up @@ -129,6 +133,15 @@ const MyPage = () => {
로그아웃
</button>
</div>

{toast.show && (
<ToastModal
message={toast.message}
icon={toast.icon}
duration={2000}
onClose={() => setToast((t) => ({ ...t, show: false }))}
/>
)}
</div>
);
};
Expand Down
3 changes: 1 addition & 2 deletions src/pages/review/StoreReviewPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const StoreReviewPage = () => {
<img
src="/svgs/storeReview/backIcon.svg"
className="w-8 h-8"
onClick={() => navigate(-1)}
onClick={() => navigate("/")}
/>
</div>

Expand All @@ -66,7 +66,6 @@ const StoreReviewPage = () => {
onCloseCamera={() => setTurnOnCamera(false)}
onCaptureSuccess={(data) => {
setCompanyInfo(data); // 즉시 로컬 상태에 저장
// setReceiptInfo(data); // 전역 상태에도 저장
setShowConfirm(true); // 그다음 Confirm 렌더링
}}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/story/components/carousel/BestStoryCarousel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Swiper, SwiperSlide } from "swiper/react";
import { Autoplay, Pagination } from "swiper/modules";
import "swiper/css";
import "swiper/css/pagination";
import "@/styles/swiper.css"; // 👈 아래의 스타일이 여기에 포함되어야 함
import "@/styles/swiper.css";
import SlideContent from "@/pages/story/components/content/SlideContent";

const BestStoryCarousel = ({ data, isLoading }) => {
Expand Down
24 changes: 22 additions & 2 deletions src/pages/support/components/step/Step6.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import { postUserInfo } from "@/apis/recommend/postUserInfo";
import { useState } from "react";
import "@/styles/spinner.css"; // ✅ 스피너 CSS import
import "@/styles/spinner.css";
import ErrorIcon from "/public/svgs/modal/errorIcon.svg?react";
import ToastModal from "@/components/common/ToastModal";

const Step6 = ({ onNext, defaultValue, userInfo, setRecommendResult }) => {
const [isLoading, setIsLoading] = useState(false);
const [toast, setToast] = useState({
show: false,
message: "",
icon: null,
});
const fireToast = (message, icon = ErrorIcon, duration = 4000) => {
setToast({ show: true, message, icon });
setTimeout(() => setToast((t) => ({ ...t, show: false })), duration);
};

const handleNext = async () => {
try {
Expand All @@ -13,7 +24,7 @@ const Step6 = ({ onNext, defaultValue, userInfo, setRecommendResult }) => {
onNext();
} catch (error) {
console.error("추천 요청 실패:", error);
alert("추천 결과를 불러오는 데 실패했어요. 다시 시도해주세요.");
fireToast("추천 결과를 불러오는 데 실패했어요.\n다시 시도해주세요.");
} finally {
setIsLoading(false);
}
Expand Down Expand Up @@ -49,6 +60,15 @@ const Step6 = ({ onNext, defaultValue, userInfo, setRecommendResult }) => {
</button>
)}
</div>

{toast.show && (
<ToastModal
message={toast.message}
icon={toast.icon}
duration={2000}
onClose={() => setToast((t) => ({ ...t, show: false }))}
/>
)}
</div>
);
};
Expand Down
3 changes: 1 addition & 2 deletions src/pages/support/components/step/Step7.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useState } from "react";
import { useNavigate } from "react-router-dom";
const Step7 = ({ onNext, defaultValue, userInfo, recommendResult }) => {
const Step7 = ({ recommendResult }) => {
const navigate = useNavigate();

return (
Expand Down
2 changes: 1 addition & 1 deletion src/pages/writeReview/components/FireTemperatureSlider.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState, useRef, useEffect } from "react";
import { useRef } from "react";
import { motion } from "framer-motion";

const FireTemperatureSlider = ({ temperature, setTemperature }) => {
Expand Down
5 changes: 1 addition & 4 deletions src/pages/writeReview/components/SelectTag.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState, useEffect } from "react";
import { useState } from "react";
import { tagList } from "@/constants/review/tagList";
import { usePaymentStore } from "@/store/paymentStore";
import { useNavigate } from "react-router-dom";
Expand All @@ -8,7 +8,6 @@ const SelectTag = ({ onNext }) => {
const navigate = useNavigate();
const setReviewInfo = usePaymentStore((s) => s.setReviewInfo);

const { reviewInfo } = usePaymentStore();
const [selectedTags, setSelectedTags] = useState([]);
const [temperature, setTemperature] = useState(50);

Expand Down Expand Up @@ -58,8 +57,6 @@ const SelectTag = ({ onNext }) => {
슬라이드하여 온도를 남겨 보세요.
</p>
<div className="flex justify-center items-center flex-col mb-10">
{/* <p className="h1 text-primary-8 text-center mt-6">0도</p> */}
{/* <img src="/svgs/review/fire.svg" className="w-52 h-56" /> */}
<FireTemperatureSlider
temperature={temperature}
setTemperature={setTemperature}
Expand Down
Loading