Skip to content

feat: 공유하기(링크, 카카오) 기능 구현#127

Merged
Yejiin21 merged 2 commits intodevelopfrom
feat/#126/share-link-kakao
May 13, 2025
Merged

feat: 공유하기(링크, 카카오) 기능 구현#127
Yejiin21 merged 2 commits intodevelopfrom
feat/#126/share-link-kakao

Conversation

@Yejiin21
Copy link
Copy Markdown
Contributor

@Yejiin21 Yejiin21 commented May 13, 2025

링크 공유하기

image

카카오 공유하기

image

Summary by CodeRabbit

  • 새로운 기능

    • 이벤트 상세 페이지에서 카카오톡으로 이벤트를 공유할 수 있는 기능이 추가되었습니다.
    • 이벤트 링크를 클립보드에 복사하는 기능이 개선되어, 더 다양한 환경에서 안정적으로 동작합니다.
  • 버그 수정

    • 클립보드 복사 기능이 지원되지 않는 브라우저에서도 예외 처리가 추가되었습니다.
  • 기타

    • 카카오 공유 기능 연동을 위해 카카오 JavaScript SDK가 추가되었습니다.

@Yejiin21 Yejiin21 requested review from hyeeuncho and xaexunxang May 13, 2025 11:19
@Yejiin21 Yejiin21 self-assigned this May 13, 2025
@Yejiin21 Yejiin21 linked an issue May 13, 2025 that may be closed by this pull request
2 tasks
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented May 13, 2025

Walkthrough

카카오톡 공유 기능과 이벤트 링크 복사 기능이 이벤트 공유 모달에 추가되었습니다. 카카오 SDK를 동적으로 로드하고, 공유 함수가 새로 도입되었으며, 타입 정의와 환경 설정이 반영되었습니다. 이벤트 상세 페이지에서는 공유 모달에 새로운 이벤트 정보가 전달됩니다.

Changes

파일/경로 변경 요약
index.html 카카오 JavaScript SDK를 로드하는 스크립트 태그가 추가됨.
src/features/event-manage/event-create/ui/ShareEventModal.tsx 카카오톡 공유 및 robust한 링크 복사 기능 추가, props 확장, 내부 핸들러 추가 및 UI 요소 업데이트.
src/pages/event/ui/EventDetailsPage.tsx ShareEventModal에 eventDescription, eventImageUrl, eventUrl props 전달 추가.
src/shared/lib/kakaoShare.ts 카카오 SDK 동적 로드 및 초기화, 카카오톡 공유 함수(shareToKakao) 신규 모듈로 도입.
src/shared/types/kakaoType.ts KakaoLinkOptions 타입 정의 및 Window 글로벌 인터페이스에 Kakao 객체 추가.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant EventDetailsPage
    participant ShareEventModal
    participant kakaoShare.ts
    participant KakaoSDK

    User->>EventDetailsPage: 이벤트 상세 페이지 진입
    EventDetailsPage->>ShareEventModal: 모달 오픈, 이벤트 정보 전달
    User->>ShareEventModal: "카카오톡으로 공유" 클릭
    ShareEventModal->>kakaoShare.ts: shareToKakao(title, desc, img, url)
    kakaoShare.ts->>KakaoSDK: SDK 동적 로드 및 초기화
    KakaoSDK-->>kakaoShare.ts: 초기화 완료
    kakaoShare.ts->>KakaoSDK: Link.sendDefault(공유 옵션)
    KakaoSDK-->>User: 카카오톡 공유 UI 표시
    User->>ShareEventModal: "링크 복사" 클릭
    ShareEventModal->>User: 클립보드에 링크 복사 및 알림
Loading

Suggested labels

🔧 Feature

Poem

🐰
카카오톡에 소식을 전해요,
이벤트 링크도 복사해요!
SDK 불러와 준비 완료,
타입 정의로 안전하게,
토끼가 뛰듯 기능이 늘었네.
오늘도 코드밭엔 새싹이 쏙!
🥕✨

Tip

⚡️ Faster reviews with caching
  • CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.

Enjoy the performance boost—your workflow just got faster.

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions
Copy link
Copy Markdown

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (5)
index.html (1)

16-16: 카카오 SDK 로드 방식 최적화 필요

이 스크립트는 카카오 공유 기능을 위한 SDK를 로드하고 있습니다. 그러나 src/shared/lib/kakaoShare.ts 파일에서도 동일한 SDK를 동적으로 로드하는 코드가 있어 중복될 수 있습니다.

두 가지 개선 방안이 있습니다:

  1. 동적 로딩만 사용하고 이 정적 스크립트 태그 제거
  2. 또는 성능 향상을 위해 async 속성 추가:
-    <script src="https://developers.kakao.com/sdk/js/kakao.js"></script>
+    <script src="https://developers.kakao.com/sdk/js/kakao.js" async></script>
src/features/event-manage/event-create/ui/ShareEventModal.tsx (4)

21-28: 카카오 공유 기능 구현이 잘 되었습니다.

비동기 함수와 오류 처리가 적절히 구현되었습니다. 다만, 비동기 작업 중 사용자에게 로딩 상태를 표시하는 기능이 있으면 더 좋을 것 같습니다.

다음과 같이 로딩 상태를 추가하는 것을 고려해 보세요:

+ import { useState } from 'react';

const ShareEventModal = ({
  // ... existing props
}: ShareEventModalProps) => {
+  const [isSharing, setIsSharing] = useState(false);

  const handleKakaoShare = async () => {
+    setIsSharing(true);
    try {
      await shareToKakao(eventName, eventDescription, eventImageUrl, eventUrl);
    } catch (error) {
      console.error('카카오 공유 실패:', error);
      alert('카카오 공유하기에 실패했습니다.');
+    } finally {
+      setIsSharing(false);
    }
  };
  
  // ... 그리고 UI 부분에 로딩 상태 표시

30-40: 주석 처리된 코드는 제거하는 것이 좋습니다.

주석으로 이유를 설명한 것은 좋지만, 프로덕션 코드에 주석 처리된 코드가 남아있는 것은 권장되지 않습니다. 실제 사용되는 구현이 아래에 있으므로 이 주석 코드는 제거하는 것이 좋습니다.

- /* navigator.clipboard가 HTTPS, localhosts 에서만 작동하므로 배포 후 코드 변경해야함
- const handleCopyLink = async () => {
-   try {
-     await navigator.clipboard.writeText(eventUrl);
-     alert('링크가 복사되었습니다!');
-   } catch (error) {
-     console.error('링크 복사 실패:', error);
-     alert('링크 복사에 실패했습니다.');
-   }
- }; 
- */

42-61: 링크 복사 기능이 견고하게 구현되었습니다.

모던 브라우저의 Clipboard API를 우선 사용하고, 지원하지 않는 환경에서는 대체 방법을 제공하는 견고한 구현입니다. 오류 처리와 사용자 피드백도 잘 구현되었습니다.

다만 사용자 경험을 개선하기 위해 alert() 대신 더 모던한 토스트 알림이나 인라인 피드백을 고려해 보세요:

  const handleCopyLink = () => {
    if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') {
      navigator.clipboard
        .writeText(eventUrl)
-        .then(() => alert('링크가 복사되었습니다!'))
+        .then(() => {
+          // 토스트 알림 또는 인라인 피드백 표시
+          setShowToast(true);
+          setTimeout(() => setShowToast(false), 3000);
+        })
        .catch(err => {
          console.error('복사 실패:', err);
-          alert('링크 복사에 실패했습니다.');
+          setErrorMessage('링크 복사에 실패했습니다.');
        });
    } else {
      // ... 나머지 코드
-      alert('링크가 복사되었습니다!');
+      setShowToast(true);
+      setTimeout(() => setShowToast(false), 3000);
    }
  };

76-79: 클릭 핸들러 연결과 커서 스타일 적용이 잘 되었습니다.

클릭 핸들러가 적절히 연결되었고, cursor-pointer 클래스를 추가하여 사용자에게 클릭 가능한 요소임을 시각적으로 알려주는 것이 좋습니다.

접근성을 향상시키기 위해 div 대신 button 요소를 사용하는 것을 고려해 보세요:

-<div onClick={handleCopyLink} className="flex items-center gap-4 cursor-pointer">
+<button 
+  onClick={handleCopyLink} 
+  className="flex items-center gap-4 cursor-pointer w-full text-left border-none bg-transparent" 
+  aria-label="링크 복사하기"
+>
  <img src={link} alt="링크" className="w-6 h-6" />
  <h2 className="text-base">링크 복사하기</h2>
-</div>
+</button>

...

-<div onClick={handleKakaoShare} className="flex items-center gap-4 cursor-pointer">
+<button 
+  onClick={handleKakaoShare} 
+  className="flex items-center gap-4 cursor-pointer w-full text-left border-none bg-transparent"
+  aria-label="카카오톡 공유하기"
+>
  <img src={kakao} alt="카카오" className="w-6 h-6" />
  <h2 className="text-base">카카오톡 공유하기</h2>
-</div>
+</button>

Also applies to: 81-84

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 328a3bf and c73fe6f.

📒 Files selected for processing (5)
  • index.html (1 hunks)
  • src/features/event-manage/event-create/ui/ShareEventModal.tsx (2 hunks)
  • src/pages/event/ui/EventDetailsPage.tsx (1 hunks)
  • src/shared/lib/kakaoShare.ts (1 hunks)
  • src/shared/types/kakaoType.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/features/event-manage/event-create/ui/ShareEventModal.tsx (1)
src/shared/lib/kakaoShare.ts (1)
  • shareToKakao (22-50)
🪛 Biome (1.9.4)
src/shared/lib/kakaoShare.ts

[error] 3-3: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (3)
src/shared/types/kakaoType.ts (1)

1-30: 타입 정의가 잘 구성되어 있습니다

카카오 공유 기능을 위한 타입 정의가 잘 구성되어 있습니다. KakaoLinkOptions 인터페이스와 Window 인터페이스 확장이 명확하게 정의되어 있습니다.

다만, 향후 카카오 SDK의 추가 기능을 사용할 계획이 있다면 더 많은 메서드에 대한 타입 정의를 추가하는 것이 좋을 것 같습니다:

interface Kakao {
  init: (key: string) => void;
  Link: {
    sendDefault: (options: KakaoLinkOptions) => void;
    // 추가 메서드들...
  };
  Channel: {
    // 채널 관련 메서드들...
  };
  // 기타 API들...
}
src/features/event-manage/event-create/ui/ShareEventModal.tsx (2)

4-4: Props 인터페이스 확장과 임포트 추가가 잘 구현되었습니다.

필요한 shareToKakao 함수를 정확히 임포트하였고, ShareEventModalProps 인터페이스에 이벤트 공유에 필요한 추가 속성들을 적절하게 정의했습니다. 선택적 매개변수로 설정한 것도 좋은 설계입니다.

Also applies to: 6-11


14-20: 기본값 설정이 잘 구현되었습니다.

컴포넌트 매개변수에 기본값을 설정하여 props가 전달되지 않은 경우에도 안전하게 작동할 수 있도록 했습니다. 특히 eventUrl의 기본값으로 현재 창의 URL을 사용한 것은 실용적인 접근입니다.

Comment on lines +134 to +142
{isModalOpen && (
<ShareEventModal
closeModal={closeModal}
eventName={title}
eventDescription={event?.result.description}
eventImageUrl={event?.result.bannerImageUrl}
eventUrl={window.location.href}
/>
)}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

이벤트 데이터 안전한 전달 보장 필요

ShareEventModal에 새로운 props를 전달하여 카카오 공유 기능을 지원하고 있습니다. 하지만 event가 undefined일 경우에 대한 처리가 불완전합니다.

다음과 같이 기본값을 제공하여 안전성을 개선하세요:

      {isModalOpen && (
        <ShareEventModal
          closeModal={closeModal}
          eventName={title}
-          eventDescription={event?.result.description}
-          eventImageUrl={event?.result.bannerImageUrl}
+          eventDescription={event?.result.description || '이벤트 설명이 없습니다.'}
+          eventImageUrl={event?.result.bannerImageUrl || '기본 이미지 URL'}
          eventUrl={window.location.href}
        />
      )}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{isModalOpen && (
<ShareEventModal
closeModal={closeModal}
eventName={title}
eventDescription={event?.result.description}
eventImageUrl={event?.result.bannerImageUrl}
eventUrl={window.location.href}
/>
)}
{isModalOpen && (
<ShareEventModal
closeModal={closeModal}
eventName={title}
eventDescription={event?.result.description || '이벤트 설명이 없습니다.'}
eventImageUrl={event?.result.bannerImageUrl || '기본 이미지 URL'}
eventUrl={window.location.href}
/>
)}

Comment on lines +22 to +50
export const shareToKakao = async (title: string, description: string, imageUrl: string, linkUrl: string) => {
await initializeKakao();

if (!window.Kakao?.Link?.sendDefault) {
throw new Error('카카오 SDK가 초기화되지 않았습니다.');
}

window.Kakao.Link.sendDefault({
objectType: 'feed',
content: {
title,
description,
imageUrl,
link: {
mobileWebUrl: linkUrl,
webUrl: linkUrl,
},
},
buttons: [
{
title: '자세히 보기',
link: {
mobileWebUrl: linkUrl,
webUrl: linkUrl,
},
},
],
});
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

공유 기능 구현이 잘 되었으나 검증 필요

카카오 공유 기능이 잘 구현되어 있습니다. 적절한 오류 처리와 함께 필요한 파라미터를 전달하고 있습니다.

다만, Maps API 키가 Link API에도 사용 가능한지 확인이 필요합니다. Maps API와 Share API의 키가 동일한 경우도 있지만, 다른 경우도 있을 수 있습니다:


🌐 Web query:

카카오 Maps API 키와 Share API 키가 동일한가요?

💡 Result:

카카오의 지도 서비스와 공유 기능을 사용하기 위해서는 각각 별도의 API 키가 필요합니다. 지도 관련 기능을 구현하려면 카카오 지도 API 키를, 공유 기능을 구현하려면 카카오 공유 API 키를 발급받아야 합니다. 이러한 API 키는 각 서비스의 개발자 사이트에서 신청할 수 있으며, 발급 과정에서 필요한 정보와 절차를 안내받을 수 있습니다.


카카오 공유 API 키 확인 필요

공유 기능 구현은 적절하지만, 카카오 지도 API 키(Maps API Key)와 공유 기능(Link API) 키는 별도입니다. 현재 프로젝트에 설정된 키가 공유용 키인지 반드시 검증해 주세요.

  • src/shared/lib/kakaoShare.ts에서 사용하는 키가 공유 API 전용 키인지 확인
  • Kakao Developers 콘솔에서 발급받은 **Link API(JavaScript Key 또는 REST API Key)**를 사용 중인지 점검

Comment on lines +1 to +20
export const initializeKakao = () => {
return new Promise<void>(resolve => {
if (window.Kakao && window.Kakao.Link) {
resolve();
return;
}

const script = document.createElement('script');
script.src = `https://developers.kakao.com/sdk/js/kakao.js`;
script.async = true;
document.head.appendChild(script);

script.onload = () => {
if (window.Kakao) {
window.Kakao.init(import.meta.env.VITE_KAKAO_MAP_API_KEY);
}
resolve();
};
});
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Kakao SDK 초기화 로직 개선 필요

카카오 SDK 초기화 함수가 잘 구현되어 있지만, 몇 가지 개선할 점이 있습니다.

  1. 정적 스크립트 태그와 동적 로딩 방식의 중복 - index.html에 이미 스크립트 태그가 있는데 여기서도 동적으로 로드하고 있습니다.
  2. 옵셔널 체이닝 사용 권장 (정적 분석 도구 힌트 반영):
-  if (window.Kakao && window.Kakao.Link) {
+  if (window.Kakao?.Link) {
    resolve();
    return;
  }
  1. 초기화 실패에 대한 오류 처리 추가:
    script.onload = () => {
      if (window.Kakao) {
-        window.Kakao.init(import.meta.env.VITE_KAKAO_MAP_API_KEY);
+        try {
+          window.Kakao.init(import.meta.env.VITE_KAKAO_MAP_API_KEY);
+          console.log('카카오 SDK가 초기화되었습니다.');
+        } catch (error) {
+          console.error('카카오 SDK 초기화 실패:', error);
+        }
      }
      resolve();
    };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const initializeKakao = () => {
return new Promise<void>(resolve => {
if (window.Kakao && window.Kakao.Link) {
resolve();
return;
}
const script = document.createElement('script');
script.src = `https://developers.kakao.com/sdk/js/kakao.js`;
script.async = true;
document.head.appendChild(script);
script.onload = () => {
if (window.Kakao) {
window.Kakao.init(import.meta.env.VITE_KAKAO_MAP_API_KEY);
}
resolve();
};
});
};
export const initializeKakao = () => {
return new Promise<void>(resolve => {
if (window.Kakao?.Link) {
resolve();
return;
}
const script = document.createElement('script');
script.src = `https://developers.kakao.com/sdk/js/kakao.js`;
script.async = true;
document.head.appendChild(script);
script.onload = () => {
if (window.Kakao) {
try {
window.Kakao.init(import.meta.env.VITE_KAKAO_MAP_API_KEY);
console.log('카카오 SDK가 초기화되었습니다.');
} catch (error) {
console.error('카카오 SDK 초기화 실패:', error);
}
}
resolve();
};
});
};
🧰 Tools
🪛 Biome (1.9.4)

[error] 3-3: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

Copy link
Copy Markdown
Contributor

@xaexunxang xaexunxang left a comment

Choose a reason for hiding this comment

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

고생하셨읍니다,

@Yejiin21 Yejiin21 merged commit 69a6f91 into develop May 13, 2025
2 checks passed
@Yejiin21 Yejiin21 deleted the feat/#126/share-link-kakao branch May 13, 2025 13:05
@Yejiin21 Yejiin21 added the 🔧 Feature 기능 구현 label May 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔧 Feature 기능 구현

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] 공유하기(링크, 카카오) 기능 구현

2 participants