Files
saju-web/app/components/ShareButtons.tsx
gahusb affbdf1a44 feat: 음력 변환, 대운 계산, 소셜 공유 기능 추가
- 음력 변환 기능 구현
  - lunar-calendar 라이브러리 추가
  - 음력-양력 변환 유틸리티 생성
  - 모든 입력 폼에 양력/음력 선택 및 윤달 옵션 추가
  - SajuForm, CompatibilityForm에 음력 지원

- 대운(大運) 계산 기능 구현
  - 10년 단위 대운 계산 알고리즘
  - 현재 대운 표시 및 해석
  - 사주팔자 결과 페이지에 대운 섹션 추가
  - 8개 대운 (80년치) 표시

- 소셜 공유 기능 구현
  - ShareButtons 컴포넌트 생성
  - 카카오톡, 페이스북, 트위터 공유
  - 네이티브 공유 API 지원
  - 링크 복사 기능
  - 모든 결과 페이지에 공유 버튼 추가

- 메타데이터 개선
  - 사이트 제목 및 설명 최적화
  - 한국어(ko) 설정
  - 카카오 SDK 추가

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 23:57:53 +09:00

163 lines
5.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import { useState } from 'react';
interface ShareButtonsProps {
title: string;
description: string;
url?: string;
}
export default function ShareButtons({ title, description, url }: ShareButtonsProps) {
const [showShareMenu, setShowShareMenu] = useState(false);
const shareUrl = url || (typeof window !== 'undefined' ? window.location.href : '');
const handleKakaoShare = () => {
if (typeof window !== 'undefined' && (window as any).Kakao) {
(window as any).Kakao.Share.sendDefault({
objectType: 'feed',
content: {
title: title,
description: description,
imageUrl: 'https://developers.kakao.com/assets/img/about/logos/kakaolink/kakaolink_btn_medium.png',
link: {
mobileWebUrl: shareUrl,
webUrl: shareUrl,
},
},
buttons: [
{
title: '자세히 보기',
link: {
mobileWebUrl: shareUrl,
webUrl: shareUrl,
},
},
],
});
} else {
alert('카카오톡 공유 기능을 사용할 수 없습니다.');
}
};
const handleFacebookShare = () => {
const facebookUrl = `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(shareUrl)}`;
window.open(facebookUrl, '_blank', 'width=600,height=400');
};
const handleTwitterShare = () => {
const twitterUrl = `https://twitter.com/intent/tweet?text=${encodeURIComponent(title)}&url=${encodeURIComponent(shareUrl)}`;
window.open(twitterUrl, '_blank', 'width=600,height=400');
};
const handleCopyLink = async () => {
try {
await navigator.clipboard.writeText(shareUrl);
alert('링크가 복사되었습니다!');
setShowShareMenu(false);
} catch (err) {
alert('링크 복사에 실패했습니다.');
}
};
const handleNativeShare = async () => {
if (navigator.share) {
try {
await navigator.share({
title: title,
text: description,
url: shareUrl,
});
setShowShareMenu(false);
} catch (err) {
console.log('Share cancelled or failed', err);
}
} else {
setShowShareMenu(true);
}
};
return (
<div className="relative">
<button
onClick={handleNativeShare}
className="bg-white rounded-xl p-6 shadow-lg hover:shadow-xl transition text-center group w-full"
>
<div className="text-4xl mb-3">📤</div>
<h3 className="text-xl font-bold text-gray-900 mb-2"></h3>
<p className="text-gray-600 text-sm"> </p>
</button>
{/* 공유 메뉴 (모바일에서 네이티브 공유가 안 될 때) */}
{showShareMenu && (
<>
{/* 배경 오버레이 */}
<div
className="fixed inset-0 bg-black bg-opacity-50 z-40"
onClick={() => setShowShareMenu(false)}
></div>
{/* 공유 메뉴 */}
<div className="fixed bottom-0 left-0 right-0 bg-white rounded-t-3xl shadow-2xl z-50 p-6 animate-slide-up">
<div className="flex justify-between items-center mb-6">
<h3 className="text-xl font-bold text-gray-900"></h3>
<button
onClick={() => setShowShareMenu(false)}
className="text-gray-500 hover:text-gray-700 text-2xl"
>
</button>
</div>
<div className="grid grid-cols-4 gap-4 mb-4">
{/* 카카오톡 */}
<button
onClick={handleKakaoShare}
className="flex flex-col items-center gap-2 p-3 rounded-xl hover:bg-gray-50 transition"
>
<div className="w-12 h-12 bg-yellow-400 rounded-full flex items-center justify-center text-2xl">
💬
</div>
<span className="text-xs text-gray-700"></span>
</button>
{/* 페이스북 */}
<button
onClick={handleFacebookShare}
className="flex flex-col items-center gap-2 p-3 rounded-xl hover:bg-gray-50 transition"
>
<div className="w-12 h-12 bg-blue-600 rounded-full flex items-center justify-center text-2xl text-white">
f
</div>
<span className="text-xs text-gray-700"></span>
</button>
{/* 트위터 */}
<button
onClick={handleTwitterShare}
className="flex flex-col items-center gap-2 p-3 rounded-xl hover:bg-gray-50 transition"
>
<div className="w-12 h-12 bg-blue-400 rounded-full flex items-center justify-center text-2xl text-white">
𝕏
</div>
<span className="text-xs text-gray-700"></span>
</button>
{/* 링크 복사 */}
<button
onClick={handleCopyLink}
className="flex flex-col items-center gap-2 p-3 rounded-xl hover:bg-gray-50 transition"
>
<div className="w-12 h-12 bg-gray-600 rounded-full flex items-center justify-center text-2xl text-white">
🔗
</div>
<span className="text-xs text-gray-700"> </span>
</button>
</div>
</div>
</>
)}
</div>
);
}