+
{t("email")}
-
{loginInfo?.email}
+
{loginInfo?.email}
-
+
{t("nickname")}
- setNickname(e.target.value)}
+ onChangeValue={setNickname}
+ css={{ width: "100%", marginLeft: "10px" }}
+ />
+
+
+ {t("account")}
+
-
-
+
@@ -288,11 +276,5 @@ const ModalModify = (props) => {
);
};
-ModalModify.propTypes = {
- profToken: PropTypes.any,
- isOpen: PropTypes.bool,
- onChangeIsOpen: PropTypes.func,
- onUpdate: PropTypes.func,
-};
-export default ModalModify;
+export default ModalMypageModify;
diff --git a/src/components/ModalPopup/ModalReportInChatting.tsx b/src/components/ModalPopup/ModalReportInChatting.tsx
deleted file mode 100644
index b400b7ca1..000000000
--- a/src/components/ModalPopup/ModalReportInChatting.tsx
+++ /dev/null
@@ -1,256 +0,0 @@
-import { ChangeEvent, FormEvent, useState } from "react";
-
-import type { Report } from "types/report";
-
-import { useAxios } from "hooks/useTaxiAPI";
-
-import Button from "components/Button";
-import Modal from "components/Modal";
-import ProfileImg from "components/User/ProfileImg";
-
-import alertAtom from "atoms/alert";
-import { useSetRecoilState } from "recoil";
-
-import regExpTest from "tools/regExpTest";
-import theme from "tools/theme";
-
-import ArrowDropDownRoundedIcon from "@mui/icons-material/ArrowDropDownRounded";
-import EditRoundedIcon from "@mui/icons-material/EditRounded";
-
-type ModalReportInChattingProps = {
- isOpen: boolean;
- onChangeIsOpen: (isOpen: boolean) => void;
- path: string;
- name: string;
- reportedId: string;
-};
-
-const ModalReportInChatting = ({
- isOpen,
- onChangeIsOpen,
- path,
- name,
- reportedId,
-}: ModalReportInChattingProps) => {
- const axios = useAxios();
- const [type, setType] = useState
("no-settlement");
- const [isSubmitted, setIsSubmitted] = useState(false);
- const [etcDetail, setEtcDetail] = useState("");
- const setAlert = useSetRecoilState(alertAtom);
-
- const styleProfImg: CSS = {
- width: "50px",
- height: "50px",
- marginLeft: "14px",
- flexShrink: 0,
- };
- const styleTitle: CSS = {
- margin: "0 24px 0 12px",
- ...theme.font16_bold,
- ...theme.ellipsis,
- color: theme.black,
- };
- const styleTop: CSS = {
- marginTop: "6px",
- width: "100%",
- display: "flex",
- alignItems: "center",
- };
- const styleMiddle: CSS = {
- margin: "18px 20px 0px",
- display: "flex",
- alignItems: "center",
- justifyContent: "center",
- };
- const styleLabel: CSS = {
- flexShrink: 0,
- ...theme.font14,
- lineHeight: "16px",
- color: theme.gray_text,
- };
- const styleDropdownContainer: CSS = {
- position: "relative",
- display: "flex",
- flex: 1,
- marginLeft: "12px",
- };
- const styleArrow: CSS = {
- position: "absolute",
- top: "6px",
- right: "9px",
- fontSize: "16px",
- color: theme.gray_text,
- zIndex: 1,
- };
- const styleDropdown = (isSubmitted: boolean) =>
- ({
- appearance: "none",
- flex: 1,
- height: "28px",
- background: theme.gray_background,
- boxShadow: theme.shadow_gray_input_inset,
- borderRadius: "6px",
- outline: "none",
- border: "none",
- padding: "6px 12px",
- ...theme.font14,
- color: theme.gray_text,
- position: "relative",
- cursor: isSubmitted ? "auto" : "pointer",
- } as CSS);
- const styleBottom: CSS = {
- marginTop: "16px",
- display: "flex",
- gap: "10px",
- justifyContent: "space-between",
- };
- const styleBottomSubmitted: CSS = {
- margin: "32px auto 22px",
- display: "flex",
- flexDirection: "column",
- alignItems: "center",
- justifyContent: "center",
- gap: "6px",
- };
- const styleETC: CSS = {
- display: "flex",
- justifyContent: "space-between",
- background: theme.gray_background,
- boxShadow: theme.shadow_gray_input_inset,
- borderRadius: "6px",
- margin: "10px 20px 0px",
- };
- const styleText: CSS = {
- flex: 1,
- padding: "8px 12px 8px 0",
- minHeight: "16px",
- ...theme.font14,
- color: theme.gray_text,
- overflow: "scroll",
- maxHeight: "calc(100vh - 320px)",
- };
- const styleIcon: CSS = {
- color: theme.black,
- fontSize: "14px",
- margin: "9px 6px 9px 12px",
- };
-
- const handleType = (event: ChangeEvent) => {
- setType(event.target.value as Report["type"]);
- };
-
- const handleSubmit = () => {
- const data: Report = {
- reportedId,
- type,
- etcDetail,
- time: new Date(),
- };
- axios({
- url: "/reports/create",
- method: "post",
- data,
- onSuccess: () => setIsSubmitted(true),
- onError: () => setAlert("신고에 실패했습니다."),
- });
- };
-
- const handleClose = () => {
- onChangeIsOpen(false);
- setIsSubmitted(false);
- setType("no-settlement");
- };
-
- const handleEtcDetail = (event: FormEvent) => {
- if (!regExpTest.reportMsg(event.currentTarget.innerText)) {
- setAlert("신고 이유는 1500자 까지 허용됩니다.");
- }
- setEtcDetail(event.currentTarget.innerText);
- };
-
- return (
-
-
-
-
사유
-
- {!isSubmitted &&
}
-
-
-
- {type === "etc-reason" ? (
-
-
-
-
- ) : null}
- {isSubmitted ? (
-
-
- 신고가 완료
- 되었습니다.
-
-
- 신고 내역은 마이 페이지에서 확인 가능합니다.
-
-
- ) : (
-
-
-
-
- )}
-
- );
-};
-
-export default ModalReportInChatting;
diff --git a/src/components/ModalPopup/index.tsx b/src/components/ModalPopup/index.tsx
index 9869fce77..48648705f 100644
--- a/src/components/ModalPopup/index.tsx
+++ b/src/components/ModalPopup/index.tsx
@@ -1,8 +1,10 @@
export { default as ModalChatCancel } from "./ModalChatCancel";
export { default as ModalChatPayement } from "./ModalChatPayment";
+export { default as ModalChatReport } from "./ModalChatReport";
+export { default as ModalChatSaveAccount } from "./ModalChatSaveAccount";
export { default as ModalChatSettlement } from "./ModalChatSettlement";
export { default as ModalCredit } from "./ModalCredit";
-export { default as ModalModify } from "./ModalModify";
+export { default as ModalMypageModify } from "./ModalMypageModify";
export { default as ModalNotification } from "./ModalNotification";
export { default as ModalPrivacyPolicy } from "./ModalPrivacyPolicy";
export { default as ModalReport } from "./ModalReport";
diff --git a/src/components/Room/index.jsx b/src/components/Room/index.jsx
index 309bbd522..bdd26ff4f 100644
--- a/src/components/Room/index.jsx
+++ b/src/components/Room/index.jsx
@@ -42,13 +42,13 @@ const Tag = (props) => {
>
);
} else if (!paid) {
- isDone = 결제 미완료
;
+ isDone = 정산 미완료
;
} else if (props.isSettlementForMe === "paid") {
- isDone = 결제 완료
;
- } else if (props.isSettlementForMe === "sent") {
isDone = 정산 완료
;
+ } else if (props.isSettlementForMe === "sent") {
+ isDone = 송금 완료
;
} else if (props.isSettlementForMe === "send-required") {
- isDone = 정산 미완료
;
+ isDone = 송금 미완료
;
}
// if (paid.length === 0) {
diff --git a/src/components/Skeleton/AlertProvider.tsx b/src/components/Skeleton/AlertProvider.tsx
index 14c8cc1f0..1ac00f560 100644
--- a/src/components/Skeleton/AlertProvider.tsx
+++ b/src/components/Skeleton/AlertProvider.tsx
@@ -48,6 +48,7 @@ const AlertProvider = () => {
wordBreak: "keep-all",
width: "fit-content",
margin: "24px auto",
+ padding: "0 8px",
}}
>
{messageCache.current}
diff --git a/src/components/User/ProfileImg.jsx b/src/components/User/ProfileImage.tsx
similarity index 59%
rename from src/components/User/ProfileImg.jsx
rename to src/components/User/ProfileImage.tsx
index 1fb3f6fb7..58bb297cd 100644
--- a/src/components/User/ProfileImg.jsx
+++ b/src/components/User/ProfileImage.tsx
@@ -1,4 +1,3 @@
-import PropTypes from "prop-types";
import { useEffect, useState } from "react";
import theme from "tools/theme";
@@ -6,18 +5,20 @@ import { getS3Url } from "tools/trans";
import defaultImg from "static/assets/profileImgOnError.png";
-const ProfileImg = (props) => {
- const getSrc = () =>
- getS3Url(`/profile-img/${props.path}?token=${props.token}`);
+type ProfileImageProps = {
+ url: string;
+ token?: string;
+};
+
+const ProfileImage = ({ url, token }: ProfileImageProps) => {
+ const getSrc = () => getS3Url(`/profile-img/${url}?token=${token || ""}`);
const [src, setSrc] = useState(getSrc());
- useEffect(() => {
- setSrc(getSrc());
- }, [props.path, props.token]);
+ useEffect(() => setSrc(getSrc()), [url, token]);
return (
{
>
{
height: "100%",
objectFit: "cover",
}}
- alt={`/profile-img/${props.path}`}
+ alt={`/profile-img/${url}`}
onError={() => setSrc(defaultImg)}
/>
);
};
-ProfileImg.propTypes = {
- path: PropTypes.string,
- token: PropTypes.string,
-};
-ProfileImg.defaultProps = {
- token: "",
-};
-
-export default ProfileImg;
+export default ProfileImage;
diff --git a/src/components/User/index.tsx b/src/components/User/index.tsx
index c18dc77d3..cc83a1423 100644
--- a/src/components/User/index.tsx
+++ b/src/components/User/index.tsx
@@ -1,46 +1,51 @@
-import ProfileImg from "./ProfileImg";
+import ProfileImage from "./ProfileImage";
import theme from "tools/theme";
-type UserProps = {
- value: User;
- // type?: "defalut" | "settlement" | "departed";
-};
+type UserProps = { value: User; isDeparted?: boolean };
-const User = ({ value }: UserProps) => (
-
+const User = ({ value, isDeparted }: UserProps) => {
+ const isSettlement =
+ value?.isSettlement === "paid" || value?.isSettlement === "sent";
+ return (
-
+
+
+ {value.nickname}
+ {isDeparted && !isSettlement && (
+ (미정산)
+ )}
+
-
- {value.nickname}
-
-
-);
+ );
+};
export default User;
diff --git a/src/hooks/chat/useAccountFromChats.tsx b/src/hooks/chat/useAccountFromChats.tsx
new file mode 100644
index 000000000..a71fa79b3
--- /dev/null
+++ b/src/hooks/chat/useAccountFromChats.tsx
@@ -0,0 +1,17 @@
+import { useMemo } from "react";
+
+import type { Chats } from "types/chat";
+
+export default (chats: Chats): Nullable => {
+ return useMemo(() => {
+ const accountChats = chats
+ .filter((chat) => chat.type === "account")
+ .reverse();
+ for (const chat of accountChats) {
+ if ("content" in chat && chat.content !== "") {
+ return chat.content;
+ }
+ }
+ return null;
+ }, [chats]);
+};
diff --git a/src/hooks/chat/useChatsForBody.tsx b/src/hooks/chat/useChatsForBody.tsx
index 35e0704c8..8bfc126d3 100644
--- a/src/hooks/chat/useChatsForBody.tsx
+++ b/src/hooks/chat/useChatsForBody.tsx
@@ -14,7 +14,7 @@ import { getChatUniquewKey } from "tools/chat/chats";
import dayjs from "tools/day";
import moment from "tools/moment";
-export default (_chats: Chats, layoutType: LayoutType) => {
+export default (_chats: Chats, layoutType: LayoutType, roomInfo: Room) => {
const { oid: userOid } = useValueRecoilState("loginInfo") || {};
return useMemo(() => {
@@ -31,6 +31,7 @@ export default (_chats: Chats, layoutType: LayoutType) => {
key={"chat" + getChatUniquewKey(chatsCache[0])}
chats={chatsCache}
layoutType={layoutType}
+ roomInfo={roomInfo}
/>
);
}
@@ -97,5 +98,5 @@ export default (_chats: Chats, layoutType: LayoutType) => {
});
popQueue();
return list;
- }, [_chats, layoutType, userOid]);
+ }, [_chats, layoutType, userOid, roomInfo]);
};
diff --git a/src/pages/Mypage/index.tsx b/src/pages/Mypage/index.tsx
index 17ab5b94d..192a50648 100644
--- a/src/pages/Mypage/index.tsx
+++ b/src/pages/Mypage/index.tsx
@@ -9,14 +9,14 @@ import Footer from "components/Footer";
import LinkLogout from "components/Link/LinkLogout";
import {
ModalCredit,
- ModalModify,
+ ModalMypageModify,
ModalNotification,
ModalPrivacyPolicy,
ModalReport,
ModalTerms,
} from "components/ModalPopup";
import Title from "components/Title";
-import ProfileImg from "components/User/ProfileImg";
+import ProfileImage from "components/User/ProfileImage";
import WhiteContainer from "components/WhiteContainer";
import WhiteContainerSuggestLogin from "components/WhiteContainer/WhiteContainerSuggestLogin";
@@ -109,8 +109,8 @@ const Mypage = () => {
{loginInfo?.profileImgUrl && (
-
)}
@@ -159,7 +159,7 @@ const Mypage = () => {
-
{
};
const styleSelect = {
- opacity: 0,
- right: 0,
- position: "absolute",
- ...theme.cursor(),
- };
-
- const styleShowOption = {
- display: "flex",
- justifyContent: "center",
- alignItems: "flex-start",
color: theme.purple,
...theme.font10_bold,
- marginRight: "-3px",
- };
-
- const styleArrowIcon = {
- color: theme.purple,
- fontSize: "11px",
+ borderRadius: "6px",
+ boxShadow: theme.shadow,
};
return (
@@ -93,23 +79,15 @@ const SearchOptions = (props) => {
만석인 방 포함하기
-
-
-
-
+
);
};
diff --git a/src/static/assets/KakaoPayLogo.svg b/src/static/assets/KakaoPayLogo.svg
new file mode 100644
index 000000000..c9e2521a1
--- /dev/null
+++ b/src/static/assets/KakaoPayLogo.svg
@@ -0,0 +1,25 @@
+
+
+
diff --git a/src/static/assets/KakaotTaxiLogo.svg b/src/static/assets/KakaoTaxiLogo.svg
similarity index 100%
rename from src/static/assets/KakaotTaxiLogo.svg
rename to src/static/assets/KakaoTaxiLogo.svg
diff --git a/src/static/assets/TossLogo.svg b/src/static/assets/TossLogo.svg
new file mode 100644
index 000000000..25eeea5aa
--- /dev/null
+++ b/src/static/assets/TossLogo.svg
@@ -0,0 +1,21 @@
+
+
+
diff --git a/src/tools/chat/chats.ts b/src/tools/chat/chats.ts
index 3fea596d6..8a7f4725a 100644
--- a/src/tools/chat/chats.ts
+++ b/src/tools/chat/chats.ts
@@ -23,7 +23,6 @@ export const createShareChat = (roomInfo: Room): BotChat => ({
authorId: "bot",
authorName: "택시 봇",
content: randomSuggestRoomShareTextGenerator(roomInfo._id),
- roomInfo,
roomId: roomInfo._id,
time: roomInfo.madeat,
isValid: true,
diff --git a/src/tools/regExpTest.js b/src/tools/regExpTest.js
index c29e44eac..8fc36d317 100644
--- a/src/tools/regExpTest.js
+++ b/src/tools/regExpTest.js
@@ -22,7 +22,7 @@ const reportMsg = (x) => {
};
const account = (x) => {
- return RegExp("^[A-Za-z가-힣]{2,7} ([0-9]{10,14}|)$").test(x);
+ return RegExp("^[A-Za-z가-힣]{2,7} [0-9]{10,14}$|^$").test(x);
};
export default { chatMsg, nickname, roomName, fromTo, reportMsg, account };
diff --git a/src/types/chat.d.ts b/src/types/chat.d.ts
index dbc09f4c4..e152cfbbe 100644
--- a/src/types/chat.d.ts
+++ b/src/types/chat.d.ts
@@ -22,7 +22,6 @@ export type BotChat = {
type: "share";
authorId: "bot";
authorName: string;
- roomInfo: Room;
} & CommonChat;
export type Chat = UserChat | GeneralChat | BotChat;
diff --git a/src/types/global.d.ts b/src/types/global.d.ts
index 691d006b3..f293636e6 100644
--- a/src/types/global.d.ts
+++ b/src/types/global.d.ts
@@ -24,6 +24,7 @@ declare global {
name: string;
nickname: string;
profileImageUrl: string;
+ isSettlement?: "not-departed" | "paid" | "send-required" | "sent";
};
type Room = {
_id: string;
@@ -34,15 +35,7 @@ declare global {
madeat: Date;
settlementTotal?: number;
maxPartLength: number;
- part: [
- {
- _id: string;
- name: string;
- nickname: string;
- profileImageUrl: string;
- isSettlement?: string;
- }
- ];
+ part: Array
;
};
type ReportResponse = { status: number };