Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f710b55
refactor: Comments 및 Hashtags μ»΄ν¬λ„ŒνŠΈμ—μ„œ λΆˆν•„μš”ν•œ div 제거 및 ꡬ쑰 κ°„μ†Œν™”
jungsunbeen May 27, 2025
1a014df
feat: _redirects 파일 μΆ”κ°€
jungsunbeen May 27, 2025
b360ba3
feat: OpenAI API 톡신을 μœ„ν•œ sendMessageToGPT ν•¨μˆ˜ μΆ”κ°€ 및 κ΄€λ ¨ μ˜μ‘΄μ„± μΆ”κ°€
jungsunbeen May 29, 2025
a255cc6
feat: Testpage μ»΄ν¬λ„ŒνŠΈ μΆ”κ°€ 및 OpenAI APIμ™€μ˜ 톡신 κΈ°λŠ₯ κ΅¬ν˜„ (근데 429뜸)
jungsunbeen May 29, 2025
0613002
refactor: API_KEY 둜그 좜λ ₯ 제거
jungsunbeen May 29, 2025
5b448f9
feat: getDiary ν•¨μˆ˜ μΆ”κ°€ν•˜μ—¬ 일기 데이터 쑰회 κΈ°λŠ₯ κ΅¬ν˜„
jungsunbeen May 29, 2025
72e3f48
feat: 일기 상세 νŽ˜μ΄μ§€μ—μ„œ diaryIdλ₯Ό μ‚¬μš©ν•˜μ—¬ 일기 데이터 쑰회 κΈ°λŠ₯ μΆ”κ°€
jungsunbeen May 29, 2025
aac00af
feat: 일기 λͺ©λ‘μ„ APIμ—μ„œ κ°€μ Έμ˜€λŠ” κΈ°λŠ₯ μΆ”κ°€ 및 λΆˆν•„μš”ν•œ 더미 데이터 제거
jungsunbeen May 29, 2025
60f0466
feat: 일기 μΉ΄λ“œ 클릭 μ‹œ 상세 νŽ˜μ΄μ§€λ‘œ μ΄λ™ν•˜λŠ” κΈ°λŠ₯ μΆ”κ°€
jungsunbeen May 29, 2025
126c3d3
refactor: μ½”λ“œ μŠ€νƒ€μΌ 톡일을 μœ„ν•œ λΆˆν•„μš”ν•œ 곡백 및 쀄 정리
jungsunbeen May 29, 2025
f7ed11a
add : 캐릭터 사진 μΆ”κ°€
jungsunbeen May 29, 2025
44cea00
Merge pull request #25 from OpenKetchupSource/feat/22
jungsunbeen May 29, 2025
9dc4476
feat: 일기 상세 νŽ˜μ΄μ§€μ— AI μ½”λ©˜νŠΈ 생성 κΈ°λŠ₯ μΆ”κ°€
jungsunbeen May 29, 2025
7f3a3f7
Merge pull request #27 from OpenKetchupSource/feat/22
jungsunbeen May 29, 2025
0118fd4
feat: PR이 λ‹«νž λ•Œ μ²΄ν¬λ¦¬μŠ€νŠΈκ°€ μ™„λ£Œλœ 경우 μ–ΈκΈ‰λœ 이슈 μžλ™ λ‹«κΈ° κΈ°λŠ₯ μΆ”κ°€
jungsunbeen May 29, 2025
34a6ec1
Merge pull request #28 from OpenKetchupSource/feat/23
jungsunbeen May 29, 2025
cbab86b
feat: PR이 λ‹«νž λ•Œ μ²΄ν¬λ¦¬μŠ€νŠΈκ°€ μ™„λ£Œλœ 경우 링크된 이슈 μžλ™ λ‹«κΈ° κΈ°λŠ₯ μΆ”κ°€
jungsunbeen May 29, 2025
71f8479
Merge pull request #29 from OpenKetchupSource/feat/23
jungsunbeen May 29, 2025
04004d3
fix: 체크리슀트 확인 μ‹œ 였λ₯˜ λ°©μ§€λ₯Ό μœ„ν•œ 쑰건 μΆ”κ°€
jungsunbeen May 29, 2025
1718088
Merge pull request #30 from OpenKetchupSource/feat/23
jungsunbeen May 29, 2025
fac295e
fix: 카카였 둜그인 λ¦¬λ‹€μ΄λ ‰νŠΈ URIλ₯Ό λ‘œμ»¬μ—μ„œ 배포된 URL둜 λ³€κ²½
jungsunbeen May 29, 2025
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
33 changes: 21 additions & 12 deletions .github/workflows/auto-merge-develop-pr.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
name: Auto Merge PR from Develop to Main
name: Close Linked Issues if Checklist Complete

on:
pull_request:
branches:
- main
types: [opened, synchronize, reopened]
types: [closed]

permissions:
contents: write
pull-requests: write
issues: write
pull-requests: read
contents: read

jobs:
auto-merge:
if: github.event.pull_request.head.ref == 'develop'
close-linked-issues:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest

steps:
- name: Enable auto-merge
uses: peter-evans/enable-pull-request-automerge@v3
- name: Check if checklist is fully complete
id: checklist
run: |
BODY="${{ github.event.pull_request.body }}"
UNCHECKED=$(echo "$BODY" | grep -c '\[ \]' || true)
if [ "$UNCHECKED" -eq 0 ]; then
echo "checklist-complete=true" >> $GITHUB_OUTPUT
else
echo "checklist-complete=false" >> $GITHUB_OUTPUT
fi
- name: Close linked issues if checklist is complete
if: steps.checklist.outputs.checklist-complete == 'true'
uses: peter-evans/close-issue@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
merge-method: merge
pull-request-number: ${{ github.event.pull_request.number }}
41 changes: 41 additions & 0 deletions .github/workflows/closed-issue.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Close Mentioned Issues if Checklist Complete

on:
pull_request:
types: [closed]

permissions:
issues: write
pull-requests: read
contents: read

jobs:
close-mentioned-issues:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Check if checklist is fully complete
id: checklist
run: |
BODY="${{ github.event.pull_request.body }}"
UNCHECKED=$(echo "$BODY" | grep -c '\[ \]')
if [ "$UNCHECKED" -eq 0 ]; then
echo "checklist-complete=true" >> $GITHUB_OUTPUT
else
echo "checklist-complete=false" >> $GITHUB_OUTPUT
fi

- name: Extract issue numbers
id: issues
run: |
BODY="${{ github.event.pull_request.body }}"
echo "ISSUES=$(echo "$BODY" | grep -oE '#[0-9]+' | tr -d '#' | tr '\n' ' ')" >> $GITHUB_OUTPUT

- name: Close mentioned issues
if: steps.checklist.outputs.checklist-complete == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
for issue in ${{ steps.issues.outputs.ISSUES }}; do
gh issue close "$issue" --repo "${{ github.repository }}"
done
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ dist-ssr
*.njsproj
*.sln
*.sw?

.env
18 changes: 18 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
},
"devDependencies": {
"@eslint/js": "^9.25.0",
"@types/node": "^22.15.24",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2",
"@types/react-router-dom": "^5.3.3",
Expand Down
1 change: 1 addition & 0 deletions public/_redirects
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* /index.html 200
Binary file added public/images/characters/앙글이.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/characters/웅이.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/characters/ν‹°λ°”λ…Έ.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import SettingPage from "./pages/chatting/SettingPage";
import ChatPage from "./pages/chatting/ChatPage";
import styled from "styled-components";
import WritingPage from "./pages/writing/WritingPage";
import Testpage from "./pages/Testpage";

function App() {
return (
Expand All @@ -19,13 +20,14 @@ function App() {
<Route path="/" element={<Home />} />
<Route path="/login" element={<LoginPage />} />
<Route path="/oauth/kakao/callback" element={<KakaoCallback />} />
<Route path="/diary/:id" element={<DiaryDetail />} />
<Route path="/diary/:diaryId" element={<DiaryDetail />} />
<Route path="/setChatting" element={<SettingPage />} />
<Route path="/chat/:chatId/:character" element={<ChatPage />} />
<Route path="/writing" element={<WritingPage />} />

<Route path="/comments" element={<Comments />} />
<Route path="/hashtags" element={<Hashtags />} />
<Route path="/test" element={<Testpage />} />
</Routes>
</Wrapper>
</BrowserRouter>
Expand Down
71 changes: 35 additions & 36 deletions src/components/home/DiaryList.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,48 @@
import { useEffect, useState } from "react";
import styled from "styled-components";
import { getAllDiary } from "../../services/apis/diary/diary";
import { useNavigate } from "react-router-dom";

const diaries = [
{
date: "2025.05.01.",
title: "μ˜€λŠ˜μ€ μ˜ν™” 보러 κ°„ λ‚ ",
tags: ["#μ·¨λ―Έ", "#νœ΄μ‹"],
content: "μž¬λ°Œμ—ˆλ‹€!".repeat(30),
},
{
date: "2025.05.01.",
title: "μ˜€λŠ˜μ€ μ˜ν™” 보러 κ°„ λ‚ ",
tags: ["#μ·¨λ―Έ", "#νœ΄μ‹"],
content: "μž¬λ°Œμ—ˆλ‹€!".repeat(30),
},
{
date: "2025.05.01.",
title: "μ˜€λŠ˜μ€ μ˜ν™” 보러 κ°„ λ‚ ",
tags: ["#μ·¨λ―Έ", "#νœ΄μ‹"],
content: "μž¬λ°Œμ—ˆλ‹€!".repeat(30),
},
{
date: "2025.05.01.",
title: "μ˜€λŠ˜μ€ μ˜ν™” 보러 κ°„ λ‚ ",
tags: ["#μ·¨λ―Έ", "#νœ΄μ‹"],
content: "μž¬λ°Œμ—ˆλ‹€!".repeat(30),
},
{
date: "2025.05.01.",
title: "μ˜€λŠ˜μ€ μ˜ν™” 보러 κ°„ λ‚ ",
tags: ["#μ·¨λ―Έ", "#νœ΄μ‹"],
content: "μž¬λ°Œμ—ˆλ‹€!".repeat(30),
},
];
interface Diary {
id: number;
date: string;
title: string;
hashTags: string[];
content: string;
}

const DiaryList = () => {
const [diaries, setDiaries] = useState<Diary[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const navigate = useNavigate();

useEffect(() => {
getAllDiary()
.then((data) => {
setDiaries(data);
setLoading(false);
})
.catch((err) => {
console.error("일기 뢈러였기 μ‹€νŒ¨:", err);
setError("일기λ₯Ό λΆˆλŸ¬μ˜€μ§€ λͺ»ν–ˆμŠ΅λ‹ˆλ‹€.");
setLoading(false);
});
}, []);

if (loading) return <div>λ‘œλ”© 쀑...</div>;
if (error) return <div>{error}</div>;

return (
<Wrapper>
<CardList>
{diaries.map((diary, index) => (
<Card key={index}>
{diaries.map((diary) => (
<Card key={diary.id} onClick={() => navigate(`/diary/${diary.id}`)}>
<DateText>{diary.date}</DateText>
<DiaryTitle>{diary.title}</DiaryTitle>
<TagWrapper>
{diary.tags.map((tag, i) => (
<Tag key={i}>{tag}</Tag>
{diary.hashTags.map((tag, i) => (
<Tag key={i}>#{tag}</Tag>
))}
</TagWrapper>
<Content>{diary.content}</Content>
Expand Down
2 changes: 1 addition & 1 deletion src/components/login/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import styled from "styled-components";
const Login = () => {
// const REST_API_KEY = 'b57e43877ad662a5a26d85d3b6ff834e';
// const REDIRECT_URI = 'http://localhost:5173/oauth/kakao/callback';
const link = `https://kauth.kakao.com/oauth/authorize?response_type=code&client_id=b57e43877ad662a5a26d85d3b6ff834e&redirect_uri=http://localhost:5173/oauth/kakao/callback`;
const link = `https://kauth.kakao.com/oauth/authorize?response_type=code&client_id=b57e43877ad662a5a26d85d3b6ff834e&redirect_uri=https://withsoulmate.netlify.app/oauth/kakao/callback`;

const loginHandler = () => {
window.location.href = link;
Expand Down
92 changes: 67 additions & 25 deletions src/pages/DiaryDetail.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,93 @@
import styled from "styled-components";
import { IoHomeOutline } from "react-icons/io5";
import { BsPencil } from "react-icons/bs";
import { useNavigate } from "react-router-dom";
import { useNavigate, useParams } from "react-router-dom";
import { useEffect, useState } from "react";
import { getDiary } from "../services/apis/diary/diary";
import { generateAIComment } from "../services/gpt/openai";

interface DiaryResponse {
id: number;
date: string;
title: string;
content: string;
comment: string;
character: string;
hashTags: string[];
}

const DiaryDetail = () => {
const navigate = useNavigate();
const { diaryId } = useParams();

const [diary, setDiary] = useState<DiaryResponse | null>(null);
const [error, setError] = useState<string | null>(null);
const [loading, setLoading] = useState<boolean>(true);
const [aiComment, setAiComment] = useState<string | null>(null);

useEffect(() => {
if (diaryId) {
getDiary(diaryId)
.then((data) => {
setDiary(data);
setLoading(false);
})
.catch((err) => {
console.error("Error fetching diary:", err);
setError("일기λ₯Ό λΆˆλŸ¬μ˜€λŠ” 데 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.");
setLoading(false);
});
}
}, [diaryId]);

useEffect(() => {
if (diary) {
generateAIComment(diary.content, diary.title)
.then((comment) => setAiComment(comment))
.catch(() => setAiComment("AI μ½”λ©˜νŠΈλ₯Ό μƒμ„±ν•˜λŠ” 데 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€."));
}
}, [diary]);

const formatDate = (rawDate: string) => {
const date = new Date(rawDate);
return `${date.getFullYear()}.${String(date.getMonth() + 1).padStart(2, "0")}.${String(date.getDate()).padStart(2, "0")}.`;
};

if (loading) return <div>λ‘œλ”© 쀑...</div>;
if (error) return <div>{error}</div>;
if (!diary) return <div>일기 데이터가 μ—†μŠ΅λ‹ˆλ‹€.</div>;

return (
<Container>
<Header>
<HomeIcon onClick={() => navigate("/")} />
<DateText>2025.05.01.</DateText>
<EditIcon />
<DateText>{formatDate(diary.date)}</DateText>
<EditIcon onClick={() => navigate(`/edit/${diary.id}`)} />
</Header>

<Body>
<Title>μ˜€λŠ˜μ€ μ˜ν™” 보러 κ°„ λ‚ </Title>
<Title>{diary.title}</Title>
<TagBox>
<Tag>#μ·¨λ―Έ</Tag>
<Tag>#νœ΄μ‹</Tag>
{diary.hashTags && diary.hashTags.length > 0 ? (
diary.hashTags.map((tag, idx) => <Tag key={idx}>#{tag}</Tag>)
) : (
<Tag>#νƒœκ·Έμ—†μŒ</Tag>
)}
</TagBox>

<Content>
μ˜€λŠ˜μ€ μ˜€λžœλ§Œμ— μ˜ν™”κ΄€μ— κ°€μ„œ μ˜ν™”λ₯Ό 보고 μ™”λ‹€. μš”μ¦˜ λ°”λΉ μ„œ μ œλŒ€λ‘œ
쉬지도 λͺ»ν–ˆλŠ”λ°, μ΄λ ‡κ²Œ μ—¬μœ λ‘­κ²Œ μ‹œκ°„μ„ λ³΄λ‚΄λ‹ˆ 기뢄이 μ°Έ μ’‹μ•˜λ‹€.
μΉœκ΅¬μ™€ 약속을 작고 미리 μ˜ˆλ§€κΉŒμ§€ ν•΄λ‘μ—ˆλŠ”λ°, λ‹€ν–‰νžˆ 쒋은 μžλ¦¬μ—μ„œ
κ΄€λžŒν•  수 μžˆμ—ˆλ‹€. <br />
<br />
보고 μ‹Άμ—ˆλ˜ μ˜ν™”λΌ κΈ°λŒ€κ°€ μ»ΈλŠ”λ°, κ·Έ κΈ°λŒ€λ₯Ό 저버리지 μ•Šκ³  정말
μž¬λ―Έμžˆμ—ˆλ‹€. λ°°μš°λ“€μ˜ 연기도 ν›Œλ₯­ν–ˆκ³ , μŠ€ν† λ¦¬λ„ νƒ„νƒ„ν•΄μ„œ 쀑간에 지루할
ν‹ˆμ΄ μ—†μ—ˆλ‹€. μ˜ν™”κ΄€ 특유의 λΆ„μœ„κΈ°, μ–΄λ‘μš΄ μ‘°λͺ…κ³Ό μ»€λ‹€λž€ 슀크린, μ›…μž₯ν•œ
μ‚¬μš΄λ“œκΉŒμ§€ λͺ¨λ“  게 λͺ°μž…감을 더해쀬닀. <br />
<br />
팝콘과 μ½œλΌλ„ 빠질 수 μ—†μ–΄μ„œ, λ¨ΉμœΌλ©΄μ„œ μ˜ν™” λ³΄λŠ” μž¬λ―Έλ„ μ μ ν–ˆλ‹€. μ—”λ”©
ν¬λ ˆλ”§μ΄ 올라갈 λ•ŒλŠ” μ•„μ‰¬μš΄ λ§ˆμŒλ„ λ“€μ—ˆμ§€λ§Œ, μ˜€λžœλ§Œμ— νžλ§λ˜λŠ” μ‹œκ°„μ„
보낸 것 κ°™μ•„ λ§Œμ‘±μŠ€λŸ½λ‹€. λ‹€μŒμ—” λ‹€λ₯Έ μž₯λ₯΄μ˜ μ˜ν™”λ„ 보러 κ°€κ³  μ‹Άλ‹€.
</Content>
<Content>{diary.content}</Content>

<CommentTitle>AI 친ꡬ의 μ½”λ©˜νŠΈ</CommentTitle>
<CommentCard>
<CharacterRow>
<CharacterImg src="/ai_character.png" alt="웅이" />
<CharacterName>웅이</CharacterName>
<CharacterImg
src={`/images/characters/${diary.character}.png`}
alt={diary.character}
/>
<CharacterName>{diary.character}</CharacterName>
</CharacterRow>
<CommentText>
μ˜€λžœλ§Œμ— μ˜ν™”κ΄€μ—μ„œ 쒋은 μ‹œκ°„ λ³΄λƒˆλ‹€λ‹ˆ λ‚΄κ°€ λ‹€ κΈ°μ˜λ‹€! λ„ˆμ˜ μ—¬μœ λ‘œμš΄
ν•˜λ£¨κ°€ μ°Έ λ”°λœ»ν•˜κ²Œ 느껴져 :)
{aiComment || "AI μ½”λ©˜νŠΈλ₯Ό 생성 μ€‘μž…λ‹ˆλ‹€..."}
</CommentText>
</CommentCard>
</Body>
Expand Down
Loading
Loading