Skip to content

Commit e56222f

Browse files
authored
Merge branch 'main' into SCRUM-89-방호영
2 parents 0772f50 + 55349c6 commit e56222f

File tree

10 files changed

+161
-112
lines changed

10 files changed

+161
-112
lines changed

.github/workflows/preview.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: GitHub Actions Vercel Preview Deployment
2+
env:
3+
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
4+
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
5+
on:
6+
push:
7+
branches-ignore:
8+
- main
9+
jobs:
10+
Deploy-Preview:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v3
14+
- name: Install Vercel CLI
15+
run: npm install --global vercel@canary
16+
- name: Pull Vercel Environment Information
17+
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
18+
- name: Build Project Artifacts
19+
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
20+
- name: Deploy Project Artifacts to Vercel
21+
run: vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ dist-ssr
2222
*.njsproj
2323
*.sln
2424
*.sw?
25+
.vercel

index.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@
1010

1111
<script
1212
type="text/javascript"
13-
src="https://developers.kakao.com/sdk/js/kakao.js"
13+
src="https://t1.kakaocdn.net/kakao_js_sdk/2.7.4/kakao.min.js"
1414
></script>
1515

1616
<script type="text/javascript">
1717
if (!Kakao.isInitialized()) {
18-
Kakao.init("1031d74aeb6c3fc870d5ad1d4a8ca92e"); // JavaScript 키 사용
18+
Kakao.init("0e75199aafea8afc76aa6dd724c8f4bd"); // JavaScript 키 사용
1919
}
2020
</script>
2121

2222
<script type="module" src="/src/main.jsx"></script>
2323
</body>
2424
</html>
25+

src/components/common/InformationBar/InformationBar.jsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,24 @@ function InformationBar({
1717
const [isModalOpen, setIsModalOpen] = useState(false);
1818
const modalRef = useRef(null);
1919
const [showToast, setShowToast] = useState(false);
20-
2120
const buttonRef = useRef(null);
2221

22+
// ✅ 카카오 SDK 초기화 (한 번만 실행)
23+
useEffect(() => {
24+
if (window.Kakao && !window.Kakao.isInitialized()) {
25+
window.Kakao.init("0e75199aafea8afc76aa6dd724c8f4bd"); // 🔥 여기에 JavaScript 키 입력
26+
console.log("✅ Kakao SDK Initialized");
27+
}
28+
}, []);
29+
2330
const shareToKakao = () => {
2431
if (window.Kakao) {
2532
window.Kakao.Share.sendDefault({
2633
objectType: "feed",
2734
content: {
28-
title: "웹사이트 공유 제목",
29-
description: "웹사이트 설명",
30-
imageUrl: "",
35+
title: "롤링페이퍼 8팀",
36+
description: "친구들에게 멋진 롤링페이퍼를 공유해 보세요!🎉",
37+
imageUrl: "https://cdn-icons-png.flaticon.com/512/5220/5220478.png",
3138
link: {
3239
mobileWebUrl: window.location.href,
3340
webUrl: window.location.href,
@@ -117,7 +124,7 @@ function InformationBar({
117124
</Button>
118125
{isModalOpen && (
119126
<Modal ref={modalRef}>
120-
<Option onClick={shareToKakao}>카카오톡 공유</Option>
127+
<Option onClick={shareToKakao}> 카카오톡 공유</Option>
121128
<Option onClick={handleCopyUrl}>URL 공유</Option>
122129
</Modal>
123130
)}

src/components/domain/rollingpaper/Card/Card.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ const CardContainer = styled.div`
1313
display: flex;
1414
align-items: center;
1515
justify-content: center;
16-
top: ${(props) => props.top || "0"}; /* top 값을 받아서 사용 */
17-
left: ${(props) => props.left || "0"}; /* left 값을 받아서 사용 */
16+
top: ${(props) => props.top || "0"};
17+
left: ${(props) => props.left || "0"};
1818
`;
1919

2020
const CircleButton = styled.button`

src/components/domain/rollingpaper/Card/CardWrite.jsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@ const EditorWrapper = styled.div.withConfig({
2222
})`
2323
.ql-editor {
2424
width: 336px;
25-
height: 106px; /* 높이를 고정 */
25+
height: 106px;
2626
font-size: 1rem !important;
2727
line-height: 28px;
2828
padding: 16px 0;
2929
background: #fff;
3030
font-family: ${(props) => props.$fontFamily || "Noto Sans KR"};
3131
text-align: ${(props) => props.$textAlign || "left"};
32-
overflow: hidden; /* 내용이 박스를 넘지 않도록 설정 */
33-
white-space: pre-wrap; /* 줄 바꿈과 공백을 유지하면서 텍스트를 자동으로 줄 바꿈 */
34-
word-wrap: break-word; /* 단어가 길 경우 줄 바꿈 */
32+
overflow: hidden;
33+
white-space: pre-wrap;
34+
word-wrap: break-word;
3535
}
3636
3737
.ql-picker.ql-font {
@@ -73,7 +73,18 @@ const CardContainer = styled.div`
7373
flex-direction: column;
7474
padding: 28px 24px;
7575
box-sizing: border-box;
76-
cursor: pointer; /* 클릭 가능하도록 커서 변경 */
76+
cursor: pointer;
77+
78+
/*눌린듯한 느낌*/
79+
transition: transform 0.1s ease, box-shadow 0.1s ease;
80+
&:hover {
81+
transform: scale(0.97);
82+
box-shadow: 0px 1px 8px rgba(0, 0, 0, 0.1);
83+
}
84+
&:active {
85+
transform: scale(0.97);
86+
box-shadow: 0px 1px 8px rgba(0, 0, 0, 0.1);
87+
}
7788
`;
7889

7990
const Header = styled.div`

src/pages/Message/MessagePage.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ const Bone = styled.div`
1515
@media (max-width: 360px) {
1616
padding: 50px 20px;
1717
}
18-
overflow: auto;
1918
`;
2019

2120
function MessagePage() {

src/pages/RollingPaper/RollingPaperPage.jsx

Lines changed: 82 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,50 @@ import styled from "styled-components";
88
import recipientsService from "../../api/services/recipientsService"; // get 요청
99

1010
const CardContainer = styled.div`
11-
width: min(100%, 1200px);
12-
margin-inline: auto;
13-
padding: 0 24px;
14-
box-sizing: border-box;
11+
margin: auto;
1512
display: flex;
1613
align-items: center;
1714
justify-content: center;
1815
19-
@media (max-width: 1248px) {
20-
padding: 0 24px;
16+
padding: 100px 24px;
17+
width: 100%;
18+
box-sizing: border-box;
19+
@media (max-width: 768px) {
20+
background-attachment: scroll;
2121
}
2222
`;
2323

2424
const DivWrap = styled.div`
2525
display: grid;
2626
grid-template-columns: repeat(3, 1fr);
27-
grid-template-rows: repeat(2, auto);
2827
gap: 28px;
29-
padding-top: 112px;
30-
28+
3129
@media (max-width: 1248px) {
3230
grid-template-columns: repeat(2, 1fr);
3331
}
3432
33+
opacity: ${({ isLoaded }) => (isLoaded ? 1 : 0)};
34+
transition: opacity 0.5s ease-in-out;
35+
`;
36+
37+
const BackgroundWrap = styled.div`
38+
background-image: ${({ backgroundImageURL }) =>
39+
backgroundImageURL
40+
? `linear-gradient(180deg, rgba(0, 0, 0, 0.54) 0%, rgba(0, 0, 0, 0.54) 100%), url(${backgroundImageURL})`
41+
: "ffffff"};
42+
background-color: ${({ bgColor }) => bgColor || "#ffffff"};
43+
min-height: calc(100vh - 65px);
44+
background-size: cover;
45+
background-repeat: no-repeat;
46+
background-position: center top;
47+
background-attachment: fixed;
48+
3549
@media (max-width: 768px) {
3650
grid-template-columns: 1fr;
3751
}
3852
`;
3953

54+
4055
const BackgroundWrap = styled.div.withConfig({
4156
shouldForwardProp: (prop) =>
4257
!["bgColor", "backgroundImageURL"].includes(prop),
@@ -49,105 +64,80 @@ const BackgroundWrap = styled.div.withConfig({
4964
background-position: center;
5065
`;
5166

67+
const colorMap = {
68+
beige: "#FFE2AD",
69+
purple: "#ECD9FF",
70+
blue: "#B1E4FF",
71+
green: "#D0F5C3",
72+
};
73+
74+
5275
function RollingPaperDetailPage() {
5376
const { id } = useParams();
54-
const postData = null;
5577
const [loading, setLoading] = useState(true);
56-
const [isRecipientLoading, setIsRecipientLoading] = useState(true);
57-
const [page, setPage] = useState(1);
5878
const [recipientData, setRecipientData] = useState({});
5979

6080
const [messages, setMessages] = useState([]);
61-
const colorMap = {
62-
beige: "#FFE2AD",
63-
purple: "#ECD9FF",
64-
blue: "#B1E4FF",
65-
green: "#D0F5C3",
66-
};
67-
68-
// 무한 스크롤 때 사용합니다다
69-
const observer = useRef(null);
70-
71-
// API 호출 함수
72-
const fetchMessages = async (page) => {
73-
try {
74-
const limit = 10;
75-
const offset = (page - 1) * limit;
76-
77-
const [messagesResponse, recipientResponse] = await Promise.all([
78-
recipientsService.getRecipientsMessages(id, limit, offset),
79-
recipientsService.getRecipientsId(id),
80-
]);
81+
const [nextUrl, setNextUrl] = useState(null);
82+
const [isLoaded, setIsLoaded] = useState(false);
83+
const lastMessageRef = useRef(null);
84+
const isFetchingRef = useRef(false);
8185

82-
setMessages((prevMessages) => {
83-
const newMessages = messagesResponse.data.results;
84-
85-
const uniqueMessages = [
86-
...prevMessages,
87-
...newMessages.filter(
88-
(message) =>
89-
!prevMessages.some((prevMessage) => prevMessage.id === message.id)
90-
),
91-
];
92-
93-
return uniqueMessages;
94-
});
86+
useEffect(() => {
87+
async function fetchInitialData() {
88+
try {
89+
const [messagesResponse, recipientResponse] = await Promise.all([
90+
recipientsService.getRecipientsMessages(id, 5, 0),
91+
recipientsService.getRecipientsId(id),
92+
]);
93+
setMessages(messagesResponse.data.results);
94+
setNextUrl(messagesResponse.data.next);
95+
setRecipientData(recipientResponse.data);
96+
} catch (error) {
97+
console.error("Error fetching messages:", error);
98+
} finally {
99+
setLoading(false);
100+
}
101+
}
102+
if (id) fetchInitialData();
103+
}, [id]);
95104

96-
setRecipientData(recipientResponse.data);
105+
97106

98-
setLoading(false);
99-
setIsRecipientLoading(false);
107+
// 메시지 로드 함수
108+
const loadMoreMessages = async () => {
109+
if (!nextUrl || isFetchingRef.current) return;
110+
isFetchingRef.current = true;
111+
try {
112+
const response = await axios.get(nextUrl);
113+
setMessages((prev) => [...prev, ...response.data.results]);
114+
setNextUrl(response.data.next);
100115
} catch (error) {
101-
setLoading(false);
116+
console.error("Error loading messages:", error);
117+
} finally {
118+
isFetchingRef.current = false;
102119
}
103120
};
104121

105-
// 메시지 로드 함수
106-
const loadMoreMessages = () => {
107-
if (loading) return;
108-
setLoading(true);
109-
setPage((prev) => prev + 1);
110-
};
111-
112122
useEffect(() => {
113-
if (!id) return;
114-
115-
fetchMessages(page);
116-
}, [page, loading]);
117-
118-
// 밑에 무한 스크롤 할 수 있음
119-
useEffect(() => {
120-
if (!observer.current) {
121-
observer.current = new IntersectionObserver(
122-
(entries) => {
123-
if (entries[0].isIntersecting) {
124-
loadMoreMessages();
125-
}
126-
},
127-
{ rootMargin: "100px" }
128-
);
129-
}
123+
if (!lastMessageRef.current) return;
124+
const observer = new IntersectionObserver(
125+
([entry]) => entry.isIntersecting && loadMoreMessages(),
126+
{ root: null, rootMargin: "100px" }
127+
);
128+
observer.observe(lastMessageRef.current);
129+
return () => observer.disconnect();
130+
}, [messages]);
130131

131-
const lastCardElement = document.getElementById("last-card");
132-
if (lastCardElement) {
133-
observer.current.observe(lastCardElement);
134-
}
135-
136-
return () => {
137-
if (observer.current && lastCardElement) {
138-
observer.current.unobserve(lastCardElement);
139-
}
140-
};
141-
}, []);
142132

143133
useEffect(() => {
144134
setTimeout(() => setIsLoaded(true), 100);
145135
}, []);
146136

147137
return (
148138
<BackgroundWrap
149-
bgColor={colorMap[recipientData?.backgroundColor] ?? colorMap.beige}
150-
backgroundImageURL={recipientData?.backgroundImageUrl ?? null}
139+
bgColor={colorMap[recipientData?.backgroundColor] ?? "#ffffff"}
140+
backgroundImageURL={recipientData?.backgroundImageURL ?? null}
151141
>
152142
<InformationBar
153143
name={recipientData?.name ?? ""}
@@ -159,15 +149,11 @@ function RollingPaperDetailPage() {
159149
setRecipientData={setRecipientData}
160150
/>
161151
<CardContainer>
162-
<DivWrap>
163-
<Card postData={postData} />
164-
{messages?.map((message) => (
165-
<div key={message.id}>
166-
<CardWrite
167-
key={message.id}
168-
message={message}
169-
fontFamily={message.font}
170-
/>
152+
<DivWrap isLoaded={isLoaded}>
153+
<Card postData={null} />
154+
{messages.map((message, index) => (
155+
<div key={message.id} ref={index === messages.length - 1 ? lastMessageRef : null}>
156+
<CardWrite message={message} fontFamily={message.font} />
171157
</div>
172158
))}
173159
{messages?.length > 0 && <div id="last-card"></div>}
@@ -177,4 +163,4 @@ function RollingPaperDetailPage() {
177163
);
178164
}
179165

180-
export default RollingPaperDetailPage;
166+
export default RollingPaperDetailPage;

0 commit comments

Comments
 (0)