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
2 changes: 1 addition & 1 deletion next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @type {import('next').NextConfig} */

const nextConfig = {
reactStrictMode: true,
reactStrictMode: false,
swcMinify: true,
images: {
remotePatterns: [
Expand Down
37 changes: 37 additions & 0 deletions src/app/(pages)/(albaform)/alba/[formId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,23 @@ import RecruitInformation from "./components/RecruitInformation";
import ApplicationStatus from "./components/ApplicationStatus";
import LoadingSpinner from "@/app/components/loading-spinner/LoadingSpinner";
import FormImage from "./components/FormImage";
import ScrapBtn from "@/app/components/button/default/ScrapBtn";
import FloatingBtn from "@/app/components/button/default/FloatingBtn";
import { IoShareSocialSharp } from "react-icons/io5";
import { handleShare } from "@/utils/kakaoShare";

interface Coords {
lat: number;
lng: number;
}

declare global {
interface Window {
Kakao: any;
kakao: any;
}
}

export default function AlbaFormDetailPage() {
const { formId } = useParams();
const [formIdState, setFormIdState] = useState<number>(0);
Expand All @@ -32,6 +43,13 @@ export default function AlbaFormDetailPage() {
libraries: ["services"],
});

// 카카오 SDK 초기화
useEffect(() => {
if (typeof window !== "undefined" && window.Kakao && !window.Kakao.isInitialized()) {
window.Kakao.init(process.env.NEXT_PUBLIC_KAKAO_APP_KEY);
}
}, []);

useEffect(() => {
if (formId) {
setFormIdState(Number(formId));
Expand Down Expand Up @@ -64,6 +82,8 @@ export default function AlbaFormDetailPage() {

return (
<div className="container flex min-h-screen flex-col px-4 lg:px-0">
{/* 카카오 공유 스트립트 */}
<Script src="https://developers.kakao.com/sdk/js/kakao.min.js" strategy="beforeInteractive" />
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍

{/* 사진영역 */}
{albaFormDetailData && (
<FormImage
Expand Down Expand Up @@ -106,6 +126,23 @@ export default function AlbaFormDetailPage() {
</div>
{/* 지원 현황 */}
{isOwner && <ApplicationStatus formId={formIdState} />}

<div className="fixed right-10 top-1/2 flex flex-col gap-5">
<ScrapBtn formId={formIdState} />
<FloatingBtn
icon={<IoShareSocialSharp />}
variant="orange"
onClick={() =>
handleShare({
title: "알바폼 공유",
description: "자세한 내용을 확인하세요!",
imageUrl: albaFormDetailData?.imageUrls[0] || "기본 이미지 URL",
mobileWebUrl: `http://example.com/form/${formIdState}`,
webUrl: `http://example.com/form/${formIdState}`,
})
}
/>
</div>
</div>
);
}
7 changes: 5 additions & 2 deletions src/app/(pages)/mypage/components/sections/ScrapsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { filterPublicOptions, filterRecruitingOptions } from "@/constants/filter
import { useRouter, usePathname, useSearchParams } from "next/navigation";
import AlbaListItem from "@/app/components/card/cardList/AlbaListItem";
import LoadingSpinner from "@/app/components/loading-spinner/LoadingSpinner";
import Link from "next/link";

const SCRAPS_PER_PAGE = 10;

Expand Down Expand Up @@ -49,7 +50,7 @@ export default function ScrapsSection() {
rootMargin: "100px",
});

// 내가 스크랩한 알폼 목록 조회
// 내가 스크랩한 목록 조회
const { data, isLoading, error, hasNextPage, fetchNextPage, isFetchingNextPage } = useMyScraps({
limit: SCRAPS_PER_PAGE,
orderBy: orderBy.scrap,
Expand Down Expand Up @@ -157,7 +158,9 @@ export default function ScrapsSection() {
<React.Fragment key={page.nextCursor}>
{page.data.map((scrap: FormListType) => (
<div key={scrap.id}>
<AlbaListItem {...scrap} />
<Link href={`/alba/${scrap.id}/`}>
<AlbaListItem {...scrap} />
</Link>
</div>
))}
</React.Fragment>
Expand Down
34 changes: 0 additions & 34 deletions src/app/components/button/default/BookmarkBtn.tsx

This file was deleted.

61 changes: 61 additions & 0 deletions src/app/components/button/default/ScrapBtn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"use client";
import React, { useState } from "react";
import { FaBookmark, FaRegBookmark } from "react-icons/fa";
import { cn } from "@/lib/tailwindUtil";
import axios from "axios";
import toast from "react-hot-toast";

interface ScrapBtnProps {
className?: string;
formId: number;
}

const ScrapBtn = ({ className = "", formId }: ScrapBtnProps) => {
const [isScraped, setIsScraped] = useState(false);

const toggleScrap = () => {
setIsScraped((prev) => !prev);
};

const handleScrap = () => {
toggleScrap();
if (!isScraped) {
// 스크랩
try {
axios.post(`/api/forms/${formId}/scrap`, { formId });
toast.success("스크랩 되었습니다.");
} catch (error) {
toggleScrap();
}
}
if (isScraped) {
// 스크랩 취소
try {
axios.delete(`/api/forms/${formId}/scrap`);
toast.success("스크랩이 취소되었습니다.");
} catch (error) {
toggleScrap();
}
return;
}
};
console.log(isScraped);

return (
<button
className={cn(
"inline-flex h-12 w-12 items-center justify-center rounded-full bg-primary-orange-50 p-2 transition-colors",
className
)}
onClick={handleScrap}
>
{isScraped ? (
<FaBookmark className={cn("text-xl text-primary-orange-300")} />
) : (
<FaRegBookmark className={cn("text-xl text-primary-orange-300")} />
)}
</button>
);
};

export default ScrapBtn;

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import ScrapBtn from "@/app/components/button/default/ScrapBtn";
import type { Meta, StoryObj } from "@storybook/react";

const meta: Meta<typeof ScrapBtn> = {
title: "Design System/Components/Button/ScrapBtn",
component: ScrapBtn,
parameters: {
layout: "centered",
},
};

export default meta;
type Story = StoryObj<typeof ScrapBtn>;

export const Bookmarked: Story = {
args: {},
render: (args) => {
return (
<div>
<ScrapBtn {...args} />
</div>
);
},
};
8 changes: 5 additions & 3 deletions src/hooks/queries/form/detail/useFormDetail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@ export const useFormDetail = ({ formId }: UseFormDetailParams) => {
throw new Error("formId가 없습니다.");
}
const response = await axios.get(`/api/forms/${formId}`);
return response.data; // 이 부분을 수정합니다.
return response.data;
},
enabled: !!formId, // formId가 유효한 경우에만 쿼리를 실행
enabled: !!formId, // formId가 유효한 경우에만 쿼리 실행
});

return {
...query,
albaFormDetailData: query.data, // response.data를 albaFormDetailData로 변경
albaFormDetailData: query.data,
isPending: query.isPending,
error: query.error,
refetch: query.refetch,
};
};

export default useFormDetail;
52 changes: 52 additions & 0 deletions src/utils/kakaoShare.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
declare global {
interface Window {
Kakao: any;
}
}

export const handleShare = (templateArgs: {
title: string;
description: string;
imageUrl: string;
mobileWebUrl: string;
webUrl: string;
}) => {
if (typeof window === "undefined" || !window.Kakao) {
alert("카카오 SDK가 로드되지 않았습니다.");
return;
}

const { Kakao } = window;

if (!Kakao.isInitialized()) {
alert("카카오 SDK가 초기화되지 않았습니다.");
return;
}

try {
Kakao.Share.sendDefault({
objectType: "feed", // 피드 템플릿
content: {
title: templateArgs.title, // 공유할 제목
description: templateArgs.description, // 설명
imageUrl: templateArgs.imageUrl, // 공유할 이미지 URL
link: {
mobileWebUrl: templateArgs.mobileWebUrl, // 모바일 웹 URL
webUrl: templateArgs.webUrl, // 웹 URL
},
},
buttons: [
{
title: "자세히 보기", // 버튼 제목
link: {
mobileWebUrl: templateArgs.mobileWebUrl, // 버튼 클릭 시 이동할 URL
webUrl: templateArgs.webUrl, // 버튼 클릭 시 이동할 URL
},
},
],
});
} catch (error) {
console.error("카카오 공유 중 오류 발생:", error);
alert("공유 중 오류가 발생했습니다. 콘솔을 확인하세요.");
}
};
Loading