Skip to content

Commit a613279

Browse files
authored
Feat/공유하기, 킵 기능#2 (#105)
* [feat]공유하기 * [feat]share * [feat]keep추가/해제 * [fix]meta데이터 타입오류수정 * [chore]파일 정리 * [fix]cocktailId 타입변경 * [refactor] 타입 빠진거 추가 * [refactor]타입 추가수정 * [refactor]파라미터id타입수정 * [style]일부 스타일 수정 * [chore]스테이징 빠진 파일 추가 * [docs]keep폴더이동
1 parent 76c6c2b commit a613279

File tree

17 files changed

+298
-50
lines changed

17 files changed

+298
-50
lines changed

src/app/api/kakao/KaKaoScript.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
'use client';
2+
3+
import Script from 'next/script';
4+
5+
declare global {
6+
interface Window {
7+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
8+
Kakao: any;
9+
}
10+
}
11+
function KaKaoScript() {
12+
const onLoad = () => {
13+
window.Kakao.init(process.env.NEXT_PUBLIC_KAKAO_JAVASCRIPT_KEY);
14+
};
15+
return <Script src="https://developers.kakao.com/sdk/js/kakao.js" async onLoad={onLoad} />;
16+
}
17+
export default KaKaoScript;

src/app/layout.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import { Toaster } from 'react-hot-toast';
44
import Header from '@/shared/components/header/Header';
55
import FooterWrapper from '@/shared/components/footer/FooterWrapper';
66
import ScrollTopBtnWrapper from '@/shared/components/scroll-top/ScrollTopBtnWrapper';
7+
import KaKaoScript from './api/kakao/KaKaoScript';
8+
79
export const metadata: Metadata = {
8-
title: 'SSOUL',
10+
title: { default: 'SSOUL', template: 'SSOUL | %s' },
11+
metadataBase: new URL('http://www.ssoul.life'),
912
description: '칵테일을 좋아하는 사람들을 위한 서비스',
1013
};
1114

@@ -35,6 +38,7 @@ export default function RootLayout({
3538

3639
<ScrollTopBtnWrapper />
3740
</body>
41+
<KaKaoScript />
3842
</html>
3943
);
4044
}

src/app/recipe/[id]/page.tsx

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,42 @@
1+
import { getApi } from '@/app/api/config/appConfig';
12
import DetailMain from '@/domains/recipe/details/DetailMain';
23
import StarBg from '@/domains/shared/components/star-bg/StarBg';
4+
import { Metadata } from 'next';
5+
6+
type RouteParams = { id: number };
7+
8+
export async function generateMetadata({
9+
params,
10+
}: {
11+
params: Promise<RouteParams>;
12+
}): Promise<Metadata> {
13+
const { id } = await params;
14+
const res = await fetch(`${getApi}/cocktails/${id}`);
15+
const recipe = await res.json();
16+
return {
17+
title: `${recipe.data.cocktailNameKo}`,
18+
description: `${recipe.data.cocktailNameKo} 레시피`,
19+
openGraph: {
20+
title: recipe.title,
21+
images: [recipe.data.cocktailImgUrl],
22+
type: 'article',
23+
},
24+
twitter: {
25+
card: 'summary_large_image',
26+
description: `${recipe.data.cocktailNameKo} 레시피`,
27+
title: `${recipe.data.cocktailNameKo}`,
28+
images: [recipe.data.cocktailImgUrl],
29+
},
30+
};
31+
}
32+
33+
async function Page({ params }: { params: Promise<RouteParams> }) {
34+
const { id } = await params;
335

4-
function Page() {
536
return (
637
<div className="w-full relative">
738
<StarBg className="absolute top-0 left-0 h-200 lg:h-200" />
8-
<DetailMain />
39+
<DetailMain id={id} />
940
</div>
1041
);
1142
}

src/domains/recipe/details/DetailItem.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,13 @@ function DetailItem({ name, nameKo, story, src, abv, glassType }: Props) {
3434
<div className="flex flex-col w-full gap-3 relative md:flex-row md:justify-between md:w-150 md:gap-20 lg:w-187.5 h-50">
3535
<div className="flex flex-col gap-1 items-center md:items-end md:w-1/2">
3636
<span>{alcoholTitle && <Label title={alcoholTitle} />}</span>
37-
<h2 className="w-fit font-serif font-bold text-right text-3xl lg:text-4xl text-secondary ">
38-
{name}
39-
</h2>
40-
<h2 className="font-serif font-bold text-right text-xl lg:text-4xl text-secondary">
41-
{nameKo}
37+
<h2 className="flex flex-col gap-2">
38+
<span className="w-fit font-serif font-bold text-right text-3xl lg:text-4xl text-secondary ">
39+
{name}
40+
</span>
41+
<span className="font-serif font-bold text-right text-xl lg:whitespace-nowrap lg:text-4xl text-secondary">
42+
{nameKo}
43+
</span>
4244
</h2>
4345
</div>
4446

src/domains/recipe/details/DetailMain.tsx

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,9 @@ import DetailList from './DetailList';
1010
import { Suspense, useEffect, useState } from 'react';
1111
import SkeletonDetail from '../skeleton/SkeletonDetail';
1212
import RecipeComment from '../components/details/RecipeComment';
13-
import { useParams } from 'next/navigation';
1413
import { getApi } from '@/app/api/config/appConfig';
1514

16-
function DetailMain() {
17-
const { id } = useParams();
18-
15+
function DetailMain({ id }: { id: number }) {
1916
const [cocktail, setCocktail] = useState();
2017

2118
const fetchData = async () => {
@@ -57,12 +54,13 @@ function DetailMain() {
5754

5855
return (
5956
<Suspense fallback={<SkeletonDetail />}>
60-
<div className="max-w-1024 page-layout py-12">
61-
<DetailsHeader />
57+
<h1 className="sr-only">${cocktailNameKo} 상세정보</h1>
58+
<div className="max-w-1024 page-layout pt-4 pb-6 sm:pb-12">
59+
<DetailsHeader id={id} />
6260

6361
<article className="flex flex-col items-center mt-4 lg:mt-0">
64-
<span className="md:bg-secondary w-1 h-100 -translate-y-19 absolute top-0 left-1/2 -translate-x-1/2 md: z-2"></span>
65-
<span className="h-3 w-3 rounded-full absolute top-80 left-1/2 -translate-x-1/2 z-99 md:bg-secondary"></span>
62+
<span className="md:bg-secondary w-1 h-104 -translate-y-19 absolute top-0 left-1/2 -translate-x-1/2 md: z-2"></span>
63+
<span className="h-3 w-3 rounded-full absolute top-82 left-1/2 -translate-x-1/2 z-2 md:bg-secondary"></span>
6664
<DetailItem
6765
name={cocktailName}
6866
nameKo={cocktailNameKo}
@@ -74,22 +72,17 @@ function DetailMain() {
7472
</article>
7573

7674
<section className="mt-20 flex flex-col gap-5">
77-
<div className="border-b-1 h-18 border-white">
78-
<div className="flex items-center gap-3">
79-
<Image src={SsuryShake} alt="" width="48" height="48" />
80-
<h3 className="text-3xl font-bold">레시피</h3>
81-
</div>
75+
<div className="border-b-1 h-18 border-white flex gap-3 items-center">
76+
<Image src={SsuryShake} alt="" width="48" height="48" />
77+
<h3 className="text-2xl font-bold">레시피</h3>
8278
</div>
8379
<DetailRecipe ingredient={ingredient} recipe={recipe} />
8480
</section>
8581

86-
<section className="mt-20" aria-labelledby="옆으로 슬라이드되는 리스트">
87-
<h2 className="sr-only">추천 칵테일 리스트</h2>
88-
<div className="border-b-1 h-18 border-white">
89-
<div className="flex items-center gap-3">
90-
<Image src={SsuryDrink} alt="" width="48" height="48" />
91-
<h3 className="text-3xl font-bold">추천리스트</h3>
92-
</div>
82+
<section className="mt-20">
83+
<div className="border-b-1 h-18 border-white flex items-center gap-3">
84+
<Image src={SsuryDrink} alt="" width="48" height="48" />
85+
<h3 className="text-2xl font-bold">추천리스트</h3>
9386
</div>
9487

9588
<div className="mt-5">

src/domains/recipe/details/DetailRecipe.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ function DetailRecipe({ ingredient, recipe }: Props) {
2020

2121
return (
2222
<div className="flex flex-col md:flex-row px-5 gap-5">
23-
<article className="flex flex-col gap-4 w-[50%]">
24-
<h4 className="text-2xl font-bold">재료</h4>
23+
<article className="flex flex-col gap-4 w-full md:w-[50%]">
24+
<h4 className="text-xl font-bold">재료</h4>
2525
<ul className="flex flex-col gap-2">
2626
{arr.map((v, i) => {
2727
return (
@@ -39,9 +39,9 @@ function DetailRecipe({ ingredient, recipe }: Props) {
3939
</ul>
4040
</article>
4141

42-
<span className="border-t-1 w-full md:w-1/2 pt-5 md:border-l-1 md:border-t-0 md:px-10 border-white">
42+
<span className="border-t-1 w-full md:w-1/2 pt-5 md:pt-0 md:border-l-1 md:border-t-0 md:px-10 border-white">
4343
<article className="flex flex-col gap-4 ">
44-
<h4 className="text-2xl font-bold">만드는 법</h4>
44+
<h4 className="text-xl font-bold">만드는 법</h4>
4545
<ol className="flex flex-col gap-2 pl-4 list-decimal">
4646
{recipes.map((v, i) => (
4747
<li key={i}>{v}</li>

src/domains/recipe/details/DetailsHeader.tsx

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,44 @@
1+
'use client';
12
import Share from '@/domains/shared/components/share/Share';
23
import BackBtn from '../components/details/BackBtn';
34
import Keep from '@/domains/shared/components/keep/Keep';
5+
import { useEffect, useState } from 'react';
6+
import ShareModal from '@/domains/shared/components/share/ShareModal';
7+
import { getApi } from '@/app/api/config/appConfig';
8+
9+
interface Meta {
10+
title: string;
11+
imageUrl: string;
12+
url: string;
13+
}
14+
15+
function DetailsHeader({ id }: { id: number }) {
16+
const [isShare, setIsShare] = useState(false);
17+
const [meta, setMeta] = useState<Meta | null>(null);
18+
const url = async () => {
19+
const res = await fetch(`${getApi}/cocktails/${id}/share`);
20+
const json = await res.json();
21+
setMeta(json.data);
22+
};
23+
useEffect(() => {
24+
url();
25+
}, []);
426

5-
function DetailsHeader() {
627
return (
7-
<div className="flex items-center justify-between ">
28+
<div className="flex items-center justify-between pb-5 sm:pb-12">
29+
{isShare && meta && (
30+
<ShareModal
31+
open={isShare}
32+
onClose={() => setIsShare(!isShare)}
33+
src={meta.imageUrl}
34+
title={meta.title}
35+
url={meta.url}
36+
/>
37+
)}
838
<BackBtn />
939
<div className="flex items-center gap-3">
10-
<Share size="sm" />
11-
<Keep />
40+
<Share size="sm" onClick={() => setIsShare(true)} />
41+
<Keep cocktailId={id} />
1242
</div>
1343
</div>
1444
);

src/domains/recipe/main/CocktailList.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,13 @@ function CocktailList({ cocktails, RecipeFetch, hasNextPage, lastId, onItemClick
3838
({ cocktailImgUrl, cocktailId, cocktailName, cocktailNameKo, alcoholStrength }) => (
3939
<li key={cocktailId} onClick={onItemClick}>
4040
<Link
41-
href={`/recipe/${String(cocktailId)}`}
41+
href={`/recipe/${cocktailId}`}
4242
onClick={() => {
4343
sessionStorage.setItem('listScrollY', String(window.scrollY));
4444
}}
4545
>
4646
<CocktailCard
47+
id={cocktailId}
4748
src={cocktailImgUrl}
4849
name={cocktailName}
4950
nameKo={cocktailNameKo}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { getApi } from '@/app/api/config/appConfig';
2+
3+
export async function postKeep(CocktailId: number) {
4+
const res = await fetch(`${getApi}/me/bar/${CocktailId}/keep`, {
5+
method: 'POST',
6+
credentials: 'include',
7+
});
8+
9+
let payload = null;
10+
try {
11+
payload = await res.json();
12+
} catch {
13+
console.error();
14+
}
15+
return payload;
16+
}
17+
18+
export async function deleteKeep(CocktailId: number) {
19+
const res = await fetch(`${getApi}/me/bar/${CocktailId}/keep`, {
20+
method: 'DELETE',
21+
credentials: 'include',
22+
});
23+
let payload = null;
24+
try {
25+
payload = await res.json();
26+
} catch {
27+
console.error();
28+
}
29+
}

src/domains/shared/components/cocktail-card/CocktailCard.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Keep from '../keep/Keep';
77
import { labelTitle } from '@/domains/recipe/utills/labelTitle';
88

99
interface Props {
10+
id?: number;
1011
src: string;
1112
name: string;
1213
nameKo?: string;
@@ -27,6 +28,7 @@ function CocktailCard({
2728
textSize1,
2829
textSize2,
2930
alcohol,
31+
id,
3032
}: Props) {
3133
const alcoholTitle = labelTitle(alcohol);
3234

@@ -42,7 +44,7 @@ function CocktailCard({
4244
{keep && (
4345
<div className="flex w-full pl-4 px-3 py-2 items-center justify-between absolute left-0 top-0">
4446
<div>{alcoholTitle && <Label title={alcoholTitle} />}</div>
45-
<Keep />
47+
{id && <Keep cocktailId={id} />}
4648
</div>
4749
)}
4850
</div>

0 commit comments

Comments
 (0)