diff --git a/package-lock.json b/package-lock.json index 0bcb2c59..82a257c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@fullcalendar/react": "^6.1.15", "@tanstack/react-query": "^5.61.3", "@tanstack/react-query-devtools": "^5.61.3", + "@types/kakao-js-sdk": "^1.39.5", "@types/react-datepicker": "^4.19.5", "date-fns": "^2.30.0", "fabric": "^6.4.3", @@ -32,7 +33,6 @@ "devDependencies": { "@types/fabric": "^5.3.9", "@types/jsonwebtoken": "^9.0.7", - "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", "autoprefixer": "10.4.20", @@ -656,11 +656,18 @@ "@types/node": "*" } }, + "node_modules/@types/kakao-js-sdk": { + "version": "1.39.5", + "resolved": "https://registry.npmjs.org/@types/kakao-js-sdk/-/kakao-js-sdk-1.39.5.tgz", + "integrity": "sha512-+u+sfAq2ZcBM4yF3zE/FDxaNq85DeLkKh8K6jP9GQwGdbIJ/IGwoAQEfkbG5tL5XHOP30b3KeHmxDFG2n1E96Q==", + "license": "MIT" + }, "node_modules/@types/node": { - "version": "20.17.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.1.tgz", - "integrity": "sha512-j2VlPv1NnwPJbaCNv69FO/1z4lId0QmGvpT41YxitRtWlg96g/j8qcv2RKsLKe2F6OJgyXhupN1Xo17b2m139Q==", + "version": "20.17.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.8.tgz", + "integrity": "sha512-ahz2g6/oqbKalW9sPv6L2iRbhLnojxjYWspAqhjvqSWBgGebEJT5GvRmk0QXPj3sbC6rU0GTQjPLQkmR8CObvA==", "dev": true, + "license": "MIT", "dependencies": { "undici-types": "~6.19.2" } diff --git a/package.json b/package.json index cdd63196..5346fb69 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@fullcalendar/react": "^6.1.15", "@tanstack/react-query": "^5.61.3", "@tanstack/react-query-devtools": "^5.61.3", + "@types/kakao-js-sdk": "^1.39.5", "@types/react-datepicker": "^4.19.5", "date-fns": "^2.30.0", "fabric": "^6.4.3", @@ -38,7 +39,6 @@ "devDependencies": { "@types/fabric": "^5.3.9", "@types/jsonwebtoken": "^9.0.7", - "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", "autoprefixer": "10.4.20", diff --git a/src/app/admin/components/preview/components/preview.tsx b/src/app/admin/components/preview/components/preview.tsx index d2c9c715..7838daa0 100644 --- a/src/app/admin/components/preview/components/preview.tsx +++ b/src/app/admin/components/preview/components/preview.tsx @@ -1,4 +1,5 @@ -import React, { SetStateAction } from "react"; +"use client"; +import React, { SetStateAction, useState } from "react"; import ProfileBox from "@app/admin/components/profile-box"; import BlockList from "@app/components/page/block-list"; @@ -7,11 +8,13 @@ interface Props { setIsOpen?: React.Dispatch>; } const Preview = ({ setIsOpen }: Props) => { + const [userId, setUserId] = useState(""); return (
- - + +
+ //
); }; diff --git a/src/app/admin/components/profile-box.tsx b/src/app/admin/components/profile-box.tsx index 1e3a1d16..7e82ee0e 100644 --- a/src/app/admin/components/profile-box.tsx +++ b/src/app/admin/components/profile-box.tsx @@ -1,5 +1,5 @@ "use client"; -import React from "react"; +import React, { useEffect } from "react"; import { twMerge } from "tailwind-merge"; import Link from "next/link"; import Image from "next/image"; @@ -8,9 +8,23 @@ import { usePathname } from "next/navigation"; import HomeMenu from "@app/admin/components/home-menu"; import { ClientRoute } from "@config/route"; -const ProfileBox = () => { +import { copyText } from "../../../lib/copy"; + +interface Props { + userId: string; +} +const ProfileBox = ({ userId }: Props) => { const pathname = usePathname(); const isAdmin = pathname === "/admin"; + const shareUrl = `https://linkle-nine.vercel.app/profile/${userId}`; + + // 카카오 로직은 도메인 주소가 필요.. + // const handleShearToKakao = () => { + // const { Kakao, location } = window; + // Kakao.Share.sendScrap({ + // requestUrl: location.href, + // }); + // }; return ( <> @@ -27,9 +41,11 @@ const ProfileBox = () => { aria-labelledby="profile-name" role="region" > -
copyText(shareUrl)} className="absolute left-2 top-3 h-8 w-8 rounded-full border-2 sm:left-3 sm:top-4 sm:h-10 sm:w-10 md:h-12 md:w-12" - aria-hidden="true" > { fill className="p-1.5 sm:p-2" /> -
+ { className="mt-2 text-base font-bold underline sm:text-lg" id="profile-name" > - momomoc + {userId} {!isAdmin && } diff --git a/src/app/components/page/block-list.tsx b/src/app/components/page/block-list.tsx index 91e63571..469fb4fa 100644 --- a/src/app/components/page/block-list.tsx +++ b/src/app/components/page/block-list.tsx @@ -25,13 +25,18 @@ const PreviewEvent = dynamic( ); interface Props { + setUserId: React.Dispatch>; setIsOpen?: React.Dispatch>; } -const BlockList = ({ setIsOpen }: Props) => { +const BlockList = ({ setIsOpen, setUserId }: Props) => { const pathname = usePathname(); - const userId = pathname.split("/")[pathname.length - 1]; + const splitPathName = pathname.split("/"); + const userId = splitPathName[splitPathName.length - 1]; const isAdmin = pathname.includes("admin"); const [blocks, setBlocks] = useState([]); + useEffect(() => { + setUserId(userId); + }, [pathname]); useEffect(() => { getBlocks().then(); @@ -39,6 +44,8 @@ const BlockList = ({ setIsOpen }: Props) => { async function getBlocks() { const blockApis = await adminApiInstance; + if (!isAdmin && !userId) return; + console.log(userId); const response = userId ? await blockApis.getProfileBlocks(userId) : await blockApis.getBlocks(); diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 6ccb6fdc..382d8710 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -3,9 +3,14 @@ import { cookies } from "next/headers"; import { ThemeToggle } from "@components/common/ui/theme-toggle"; import ReactQueryProvider from "@components/providers/React-Query-Provider"; + //styles import "@styles/global.css"; import "@styles/common.css"; +import Script from "next/script"; +import React from "react"; + +import KakaoScript from "../utils/kakao-script"; export const metadata: Metadata = { title: { @@ -39,6 +44,11 @@ export const metadata: Metadata = { }; type Theme = "light" | "dark" | undefined; +declare global { + interface Window { + Kakao: any; + } +} export default function RootLayout({ children, }: Readonly<{ @@ -54,6 +64,7 @@ export default function RootLayout({ + ); } diff --git a/src/lib/copy.tsx b/src/lib/copy.tsx new file mode 100644 index 00000000..4e1b4700 --- /dev/null +++ b/src/lib/copy.tsx @@ -0,0 +1,8 @@ +export const copyText = async (textToCopy: string) => { + try { + await navigator.clipboard.writeText(textToCopy); + alert("프로필 주소가 클립보드에 복사되었어요\n 친구들에게 공유해보세요😊"); + } catch (err) { + console.error("Copy failed: ", err); + } +}; diff --git a/src/utils/kakao-script.tsx b/src/utils/kakao-script.tsx new file mode 100644 index 00000000..046ac6ec --- /dev/null +++ b/src/utils/kakao-script.tsx @@ -0,0 +1,90 @@ +"use client"; +import React from "react"; +import Script from "next/script"; + +const KakaoScript = () => { + const onLoad = () => { + if (typeof window === undefined) return; + window.Kakao.init(process.env.NEXT_PUBLIC_KAKAO_JS_KEY); + window.Kakao.Share.createDefaultButton({ + container: "#kakaotalk-sharing-btn", + objectType: "feed", + content: { + title: "오늘의 디저트", + description: "아메리카노, 빵, 케익", + imageUrl: + "https://mud-kage.kakao.com/dn/NTmhS/btqfEUdFAUf/FjKzkZsnoeE4o19klTOVI1/openlink_640x640s.jpg", + link: { + mobileWebUrl: "https://developers.kakao.com", + webUrl: "https://developers.kakao.com", + }, + }, + itemContent: { + profileText: "Kakao", + profileImageUrl: + "https://mud-kage.kakao.com/dn/Q2iNx/btqgeRgV54P/VLdBs9cvyn8BJXB3o7N8UK/kakaolink40_original.png", + titleImageUrl: + "https://mud-kage.kakao.com/dn/Q2iNx/btqgeRgV54P/VLdBs9cvyn8BJXB3o7N8UK/kakaolink40_original.png", + titleImageText: "Cheese cake", + titleImageCategory: "Cake", + items: [ + { + item: "Cake1", + itemOp: "1000원", + }, + { + item: "Cake2", + itemOp: "2000원", + }, + { + item: "Cake3", + itemOp: "3000원", + }, + { + item: "Cake4", + itemOp: "4000원", + }, + { + item: "Cake5", + itemOp: "5000원", + }, + ], + sum: "Total", + sumOp: "15000원", + }, + social: { + likeCount: 10, + commentCount: 20, + sharedCount: 30, + }, + buttons: [ + { + title: "웹으로 이동", + link: { + mobileWebUrl: "https://developers.kakao.com", + webUrl: "https://developers.kakao.com", + }, + }, + { + title: "앱으로 이동", + link: { + mobileWebUrl: "https://developers.kakao.com", + webUrl: "https://developers.kakao.com", + }, + }, + ], + }); + }; + return ( +