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
21 changes: 21 additions & 0 deletions .github/workflows/preview.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: GitHub Actions Vercel Preview Deployment
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
on:
push:
branches-ignore:
- main
jobs:
Deploy-Preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Vercel CLI
run: npm install --global vercel@canary
- name: Pull Vercel Environment Information
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
- name: Build Project Artifacts
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
- name: Deploy Project Artifacts to Vercel
run: vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ dist-ssr
*.njsproj
*.sln
*.sw?
.vercel
5 changes: 3 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@

<script
type="text/javascript"
src="https://developers.kakao.com/sdk/js/kakao.js"
src="https://t1.kakaocdn.net/kakao_js_sdk/2.7.4/kakao.min.js"
></script>

<script type="text/javascript">
if (!Kakao.isInitialized()) {
Kakao.init("1031d74aeb6c3fc870d5ad1d4a8ca92e"); // JavaScript 키 사용
Kakao.init("0e75199aafea8afc76aa6dd724c8f4bd"); // JavaScript 키 사용
}
</script>

<script type="module" src="/src/main.jsx"></script>
</body>
</html>

17 changes: 12 additions & 5 deletions src/components/common/InformationBar/InformationBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,24 @@ function InformationBar({
const [isModalOpen, setIsModalOpen] = useState(false);
const modalRef = useRef(null);
const [showToast, setShowToast] = useState(false);

const buttonRef = useRef(null);

// ✅ 카카오 SDK 초기화 (한 번만 실행)
useEffect(() => {
if (window.Kakao && !window.Kakao.isInitialized()) {
window.Kakao.init("0e75199aafea8afc76aa6dd724c8f4bd"); // 🔥 여기에 JavaScript 키 입력
console.log("✅ Kakao SDK Initialized");
}
}, []);

const shareToKakao = () => {
if (window.Kakao) {
window.Kakao.Share.sendDefault({
objectType: "feed",
content: {
title: "웹사이트 공유 제목",
description: "웹사이트 설명",
imageUrl: "",
title: "롤링페이퍼 8팀",
description: "친구들에게 멋진 롤링페이퍼를 공유해 보세요!🎉",
imageUrl: "https://cdn-icons-png.flaticon.com/512/5220/5220478.png",
link: {
mobileWebUrl: window.location.href,
webUrl: window.location.href,
Expand Down Expand Up @@ -117,7 +124,7 @@ function InformationBar({
</Button>
{isModalOpen && (
<Modal ref={modalRef}>
<Option onClick={shareToKakao}>카카오톡 공유</Option>
<Option onClick={shareToKakao}> 카카오톡 공유</Option>
<Option onClick={handleCopyUrl}>URL 공유</Option>
</Modal>
)}
Expand Down
4 changes: 2 additions & 2 deletions src/components/domain/rollingpaper/Card/Card.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ const CardContainer = styled.div`
display: flex;
align-items: center;
justify-content: center;
top: ${(props) => props.top || "0"}; /* top 값을 받아서 사용 */
left: ${(props) => props.left || "0"}; /* left 값을 받아서 사용 */
top: ${(props) => props.top || "0"};
left: ${(props) => props.left || "0"};
`;

const CircleButton = styled.button`
Expand Down
21 changes: 16 additions & 5 deletions src/components/domain/rollingpaper/Card/CardWrite.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@ const EditorWrapper = styled.div.withConfig({
})`
.ql-editor {
width: 336px;
height: 106px; /* 높이를 고정 */
height: 106px;
font-size: 1rem !important;
line-height: 28px;
padding: 16px 0;
background: #fff;
font-family: ${(props) => props.$fontFamily || "Noto Sans KR"};
text-align: ${(props) => props.$textAlign || "left"};
overflow: hidden; /* 내용이 박스를 넘지 않도록 설정 */
white-space: pre-wrap; /* 줄 바꿈과 공백을 유지하면서 텍스트를 자동으로 줄 바꿈 */
word-wrap: break-word; /* 단어가 길 경우 줄 바꿈 */
overflow: hidden;
white-space: pre-wrap;
word-wrap: break-word;
}

.ql-picker.ql-font {
Expand Down Expand Up @@ -73,7 +73,18 @@ const CardContainer = styled.div`
flex-direction: column;
padding: 28px 24px;
box-sizing: border-box;
cursor: pointer; /* 클릭 가능하도록 커서 변경 */
cursor: pointer;

/*눌린듯한 느낌*/
transition: transform 0.1s ease, box-shadow 0.1s ease;
&:hover {
transform: scale(0.97);
box-shadow: 0px 1px 8px rgba(0, 0, 0, 0.1);
}
&:active {
transform: scale(0.97);
box-shadow: 0px 1px 8px rgba(0, 0, 0, 0.1);
}
`;

const Header = styled.div`
Expand Down
1 change: 0 additions & 1 deletion src/pages/Message/MessagePage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ const Bone = styled.div`
@media (max-width: 360px) {
padding: 50px 20px;
}
overflow: auto;
`;

function MessagePage() {
Expand Down
71 changes: 25 additions & 46 deletions src/pages/RollingPaper/RollingPaperPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,12 @@ import axios from "axios";


const CardContainer = styled.div`
width: min(100%, 1200px);
margin-inline: auto;
padding: 0 24px;
box-sizing: border-box;
margin: auto;
display: flex;
justify-content: center;
height: 1140px;
min-height: 50vh;
padding: 100px 24px;
width: 100%;

background-image: ${({ backgroundImageURL }) => backgroundImageURL ? `url(${backgroundImageURL})` : "none"};
background-color: ${({ bgColor }) => bgColor || "#FFE2AD"};
min-height: calc(100vh - 65px);
height: auto;
background-size: cover;
background-repeat: no-repeat;
background-position: center top;
background-attachment: fixed;

box-sizing: border-box;
@media (max-width: 768px) {
background-attachment: scroll;
}
Expand All @@ -37,54 +23,49 @@ const CardContainer = styled.div`
const DivWrap = styled.div`
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, auto);
gap: 28px;
opacity: ${({ isLoaded }) => (isLoaded ? 1 : 0)};
transition: opacity 0.5s ease-in-out;
height: fit-content;
padding-top: 112px;

`;

const BackgroundWrap = styled.div`
background-image: ${({ backgroundImageURL }) => backgroundImageURL ? `url(${backgroundImageURL})` : "none"};
background-color: ${({ bgColor }) => bgColor || "#FFE2AD"};
min-height: 100vh;
height: auto;
background-size: contain;
background-image: ${({ backgroundImageURL }) =>
backgroundImageURL
? `linear-gradient(180deg, rgba(0, 0, 0, 0.54) 0%, rgba(0, 0, 0, 0.54) 100%), url(${backgroundImageURL})`
: "ffffff"};
background-color: ${({ bgColor }) => bgColor || "#ffffff"};
min-height: calc(100vh - 65px);
background-size: cover;
background-repeat: no-repeat;
background-position: center top;
background-attachment: fixed;

@media (max-width: 768px) {
background-attachment: scroll;
}
`;

const colorMap = {
beige: "#FFE2AD",
purple: "#ECD9FF",
blue: "#B1E4FF",
green: "#D0F5C3",
};

function RollingPaperDetailPage() {
const { id } = useParams();
const [loading, setLoading] = useState(true);
const [recipientData, setRecipientData] = useState({});
const [messages, setMessages] = useState([]);
const [nextUrl, setNextUrl] = useState(null);
const [isLoaded, setIsLoaded] = useState(false);
const observerRef = useRef(null);
const lastMessageRef = useRef(null);
const isFetchingRef = useRef(false);

const colorMap = {
beige: "#FFE2AD",
purple: "#ECD9FF",
blue: "#B1E4FF",
green: "#D0F5C3",
};


useEffect(() => {
async function fetchInitialData() {
try {
const [messagesResponse, recipientResponse] = await Promise.all([
recipientsService.getRecipientsMessages(id, 8, 0),
recipientsService.getRecipientsMessages(id, 5, 0),
recipientsService.getRecipientsId(id),
]);
setMessages(messagesResponse.data.results);
Expand All @@ -99,7 +80,6 @@ function RollingPaperDetailPage() {
if (id) fetchInitialData();
}, [id]);


const loadMoreMessages = async () => {
if (!nextUrl || isFetchingRef.current) return;
isFetchingRef.current = true;
Expand All @@ -116,21 +96,21 @@ function RollingPaperDetailPage() {

useEffect(() => {
if (!lastMessageRef.current) return;
observerRef.current = new IntersectionObserver(
const observer = new IntersectionObserver(
([entry]) => entry.isIntersecting && loadMoreMessages(),
{ root: null, rootMargin: "-50px" }
{ root: null, rootMargin: "100px" }
);
observerRef.current.observe(lastMessageRef.current);
return () => observerRef.current?.disconnect();
}, [messages.length]);
observer.observe(lastMessageRef.current);
return () => observer.disconnect();
}, [messages]);

useEffect(() => {
setTimeout(() => setIsLoaded(true), 100);
}, []);

return (
<BackgroundWrap
bgColor={colorMap[recipientData?.backgroundColor] ?? colorMap.beige}
bgColor={colorMap[recipientData?.backgroundColor] ?? "#ffffff"}
backgroundImageURL={recipientData?.backgroundImageURL ?? null}
>
<InformationBar
Expand All @@ -140,8 +120,7 @@ function RollingPaperDetailPage() {
topReactions={recipientData?.topReactions ?? []}
setRecipientData={setRecipientData}
/>
<CardContainer bgColor={colorMap[recipientData?.backgroundColor] ?? colorMap.beige}
backgroundImageURL={recipientData?.backgroundImageURL ?? null}>
<CardContainer>
<DivWrap isLoaded={isLoaded}>
<Card postData={null} />
{messages.map((message, index) => (
Expand All @@ -155,4 +134,4 @@ function RollingPaperDetailPage() {
);
}

export default RollingPaperDetailPage;
export default RollingPaperDetailPage;
15 changes: 15 additions & 0 deletions vercel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"rewrites": [
{ "source": "/(.*)", "destination": "/index.html", "statusCode": 200 }
],
"headers": [
{
"source": "/assets/(.*).js",
"headers": [{ "key": "Content-Type", "value": "application/javascript" }]
},
{
"source": "/assets/(.*).css",
"headers": [{ "key": "Content-Type", "value": "text/css" }]
}
]
}
10 changes: 9 additions & 1 deletion vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@ import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import svgr from "vite-plugin-svgr";

// https://vite.dev/config/
export default defineConfig({
plugins: [react(), svgr()],
base: '/', // ✅ Vercel 배포 시 '/' 유지
build: {
outDir: 'dist',
assetsDir: 'assets',
},
resolve: {
alias: {
"@src": "/src",
},
},
server: {
strictPort: true,
historyApiFallback: true, // ✅ 추가! React Router가 정상 작동하도록 설정
},
});
Loading