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
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
</head>
<body>
<div id="root"></div>
<script src="https://developers.kakao.com/sdk/js/kakao.js"></script>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
5 changes: 4 additions & 1 deletion public/icon/close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions public/icon/kakaotalk.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/icon/twitter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 54 additions & 0 deletions src/components/button/KakaoShareButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { useEffect } from "react";

interface KakoShareButtonProps {
title: string;
description: string;
imageUrl: string;
}

const KakaoShareButton = ({
title,
description,
imageUrl
}: KakoShareButtonProps) => {
const kakaoJavascriptKey = import.meta.env.VITE_KAKAO_JAVASCRIPT_KEY;

useEffect(() => {
// 카카오톡 SDK 초기화
if (window.Kakao && !window.Kakao.isInitialized()) {
window.Kakao.init(kakaoJavascriptKey);
}
}, []);

const handleShare = () => {
if (window.Kakao) {
// 카카오톡 공유 기능 호출
window.Kakao.Share.sendDefault({
objectType: "feed",
content: {
title: title,
description: description,
imageUrl: imageUrl,
link: {
mobileWebUrl: window.location.href,
webUrl: window.location.href
}
}
});
}
};
return (
<div>
<button onClick={handleShare}>
<img
src="/icon/kakaotalk.svg"
alt="카카오톡 공유하기 버튼"
width={72}
height={72}
/>
</button>
</div>
);
};

export default KakaoShareButton;
22 changes: 16 additions & 6 deletions src/components/button/ShareButton.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { useState } from "react";
import ShareModal from "@/components/modal/ShareModal";

const ShareButton = () => {
return (
<button className="flex justify-center items-center bg-primary-pale border border-primary-light rounded-lg w-full h-[60px] font-bold text-primary-normal">
공유하기
const [shareModalIsOpen, setShareModalIsOpen] = useState(false);

return (
<>
<button onClick={()=>setShareModalIsOpen(true)} className="flex h-[60px] w-full items-center justify-center rounded-lg border border-primary-light bg-primary-pale font-bold text-primary-normal">
공유하기
</button>
)
}
{shareModalIsOpen && (
<ShareModal closeModal={() => setShareModalIsOpen(false)} />
)}
</>
);
};

export default ShareButton;
export default ShareButton;
15 changes: 15 additions & 0 deletions src/components/button/TwitterShareButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const TwitterShareButton = ({ title }: { title: string }) => {
const currentUrl = window.location.href;

return (
<a
href={`https://twitter.com/intent/tweet?text=${title}&url=${currentUrl}`}
className="flex flex-col items-center gap-1"
>
<img src="/icon/twitter.svg" alt="트위터 아이콘" width={76} height={76} />
<p className="text-md text-gray-800">트위터</p>
</a>
);
};

export default TwitterShareButton;
14 changes: 14 additions & 0 deletions src/components/button/UrlCopyBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import UrlCopyButton from "@/components/button/UrlCopyButton";

const UrlCopyBar = () => {
const currentUrl = window.location.href;

return (
<div className="flex h-[54px] w-full max-w-[420px] items-center justify-between rounded-lg border border-gray-100 px-4 py-[15px]">
<span className="text-lg ">{currentUrl}</span>
<UrlCopyButton currentUrl={currentUrl} />
</div>
);
};

export default UrlCopyBar;
23 changes: 23 additions & 0 deletions src/components/button/UrlCopyButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const UrlCopyButton = ({currentUrl} : {currentUrl : string}) => {
const handleCopy = () => {
navigator.clipboard
.writeText(currentUrl)
.then(() => {
alert("URL이 복사되었습니다!"); // toast로 바꾸어야 함 -> 4.10 정준영
})
.catch((err) => {
console.error("URL 복사 실패:", err);
});
};

return (
<button
onClick={handleCopy}
className="bg-primary-normal h-8 text-white flex items-center justify-center rounded-[20px] px-4 py-2"
>
복사
</button>
);
};

export default UrlCopyButton;
2 changes: 1 addition & 1 deletion src/components/header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type HeaderProps = {
const Header = ({
title = "",
showPreviousIcon = true,
showShareIcon = false,
showShareIcon = true,
children
}: HeaderProps) => {
const { pathname } = useLocation();
Expand Down
37 changes: 25 additions & 12 deletions src/components/header/SubHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useLocation, useNavigate } from "react-router-dom";
import { useState } from "react";
import useMbtiTestState from "@/store/useMbtiTestState";
import ActionConfirmModal from "@/components/modal/ActionConfirmModal";
import ShareModal from "@/components/modal/ShareModal";

type SubHeaderProps = {
title: string;
Expand All @@ -12,13 +13,13 @@ type SubHeaderProps = {
const SubHeader = ({
title = "",
showPreviousIcon = true,
showShareIcon = false
showShareIcon = true
}: SubHeaderProps) => {
const navigate = useNavigate();
const { pathname, state } = useLocation();
const { currentPage, setPreviousStep } = useMbtiTestState();
const [isLeaveChatModalOpen, setIsLeaveChatModalOpen] = useState(false);

const [shareModalIsOpen, setShareModalIsOpen] = useState(false);
const isProgressPage = pathname === "/mbti-test-progress";
const isChatPage = pathname === "/chat";
const isFirstQuestionPage = currentPage === 1;
Expand Down Expand Up @@ -50,30 +51,34 @@ const SubHeader = ({

return (
<>
<header className="relative flex h-[56px] w-full flex-row items-center justify-center border-b border-gray-100 bg-white">
<header className="relative flex h-[56px] w-full items-center justify-between border-b border-gray-100 bg-white">
{showPreviousIcon && (
<img
src="/public/icon/arrow_left.svg"
alt="Go To Back"
className="absolute left-[18.77px] cursor-pointer"
className="absolute left-4 cursor-pointer"
width={9}
height={16}
onClick={handleGoBack}
/>
)}

<h1 className="absolute left-1/2 -translate-x-1/2 transform font-bold text-gray-900">
<h1 className="absolute left-1/2 -translate-x-1/2 font-bold text-gray-900">
{title}
</h1>

{showShareIcon && (
<img
src="/public/icon/share.svg"
alt="Share"
className="absolute right-[20px] cursor-pointer"
width={16}
height={16}
/>
<button
onClick={() => setShareModalIsOpen(true)}
className="absolute right-4"
>
<img
src="/public/icon/share.svg"
alt="Share"
width={16}
height={16}
/>
</button>
)}
</header>

Expand All @@ -87,6 +92,14 @@ const SubHeader = ({
onConfirm={handleConfirm}
/>
)}

{shareModalIsOpen && (
<ShareModal
closeModal={() => {
setShareModalIsOpen(false);
}}
/>
)}
</>
);
};
Expand Down
63 changes: 63 additions & 0 deletions src/components/modal/ShareModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { useEffect, useState } from "react";
import UrlCopyBar from "@/components/button/UrlCopyBar";
import TwitterShareButton from "@/components/button/TwitterShareButton";
import KakaoShareButton from "@/components/button/KakaoShareButton";

interface ShareModalProps {
closeModal: () => void;
}

const ShareModal = ({ closeModal }: ShareModalProps) => {
const [metaData, setMetaData] = useState({
title: "",
description: "",
imageUrl: ""
});

useEffect(() => {
// 메타 데이터를 가져오는 로직
const title =
document
.querySelector("meta[property='og:title']")
?.getAttribute("content") || document.title;
const description =
document
.querySelector("meta[property='og:description']")
?.getAttribute("content") || "";
const imageUrl =
document
.querySelector("meta[property='og:image']")
?.getAttribute("content") || "";

setMetaData({ title, description, imageUrl });
}, []);

return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
<main className="relative z-51 flex h-[310px] flex-col justify-center rounded-[20px] bg-white">
<h2 className="w-full border-b-gray-100 text-center text-xl font-bold ">
게시글 공유
</h2>
<div className="mt-10 flex justify-center gap-10">
<KakaoShareButton
title={metaData.title}
description={metaData.description}
imageUrl={metaData.imageUrl}
/>
<TwitterShareButton title={metaData.title} />
</div>
<button
onClick={closeModal}
className="absolute top-[14px] right-[14px] h-6 w-6"
>
<img src="/icon/close.svg" alt="닫기 버튼" width={24} height={24} />
</button>
<div className="mt-10 flex w-full justify-center">
<UrlCopyBar />
</div>
</main>
</div>
);
};

export default ShareModal;
4 changes: 4 additions & 0 deletions src/global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// TypeScript 사용 시에는 TypeScript 가 window객체에 존재하는 Kakao객체를 인식할 수 있도록 src내에 global.d.ts를 설정해줘야 오류가 발생하지 않는다.
interface Window {
Kakao: any;
}
4 changes: 0 additions & 4 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,6 @@ button {
cursor: pointer;
}

button:hover {
opacity: 80%;
}

@keyframes pulse-custom {
0%,
100% {
Expand Down
7 changes: 1 addition & 6 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./App";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 왜 제거되었을까요,,?


createRoot(document.getElementById("root")!).render(
<StrictMode>
<App />
</StrictMode>
);
createRoot(document.getElementById("root")!).render(<App />);
9 changes: 9 additions & 0 deletions src/types/virtualFreind.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export interface VirtualFriend {
virtualFriendId: number;
conversationId: number;
mbti: string;
virtualFriendName: string;
virtualFriendAge: number;
virtualFriendSex: string;
virtualFriendRelationship: string;
}