From f0df3240df1d992109245f665446ad0932d7f776 Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Fri, 24 Nov 2023 13:55:55 +0900 Subject: [PATCH 01/80] =?UTF-8?q?fix:=20=EB=AC=B4=ED=95=9C=EB=A6=AC?= =?UTF-8?q?=EB=A0=8C=EB=8D=94=EB=A7=81=20=EC=98=A4=EB=A5=98=ED=95=B4?= =?UTF-8?q?=EA=B2=B0=20=EB=B0=8F=20api=EC=97=90=20=EB=94=B0=EB=9D=BC=20?= =?UTF-8?q?=EB=B3=80=EC=88=98=EB=AA=85=EB=B3=80=EA=B2=BD=20#62?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/ContentPhoto.tsx | 8 ++++---- src/component/Modal/Photo.tsx | 10 ++++++---- src/component/ObserveContent.tsx | 12 ++++++------ src/recoil/observe.ts | 2 +- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/component/ContentPhoto.tsx b/src/component/ContentPhoto.tsx index e6b9ca88..4e29bb99 100644 --- a/src/component/ContentPhoto.tsx +++ b/src/component/ContentPhoto.tsx @@ -9,15 +9,15 @@ export default function ContentPhoto() { const [observe] = useRecoilState(observeState); return (
- {observe.photo && observe.photo.length !== 0 && ( - 사진 { - openModal(); + openModal(); }} /> )} diff --git a/src/component/Modal/Photo.tsx b/src/component/Modal/Photo.tsx index 0555a877..c87f06a3 100644 --- a/src/component/Modal/Photo.tsx +++ b/src/component/Modal/Photo.tsx @@ -1,10 +1,12 @@ -import Image from 'next/image'; +interface Props { + photoUrl: string; +} -export default function Photo(photo: any) { +export default function Photo({ photoUrl }: Props) { return (
- 사진 { setObserve(() => ({ boardId: boardId, contentId: content.id, - photo: content.photo, + photoUrl: content.photo, writer: content.writer, })); } @@ -41,7 +41,7 @@ const ObserveContent = ({ content, boardId, isAdd }: props) => { return () => { observer.disconnect(); }; - }); + }, [boardId, content.id, content.photo, content.writer, setObserve]); return (
@@ -52,20 +52,20 @@ const ObserveContent = ({ content, boardId, isAdd }: props) => { !isAdd && observe.boardId === boardId && observe.contentId === content.id - ? `${theme.FontColor1} ' duration-500' inline w-full text-[24px] opacity-100 transition-all` - : `${theme.DefaultFontColor} ' duration-500' inline w-full text-[24px] opacity-30 transition-all` + ? `${theme.FontColor1} ' duration-500' inline w-full text-[22px] opacity-100 transition-all` + : `${theme.DefaultFontColor} ' duration-500' inline w-full text-[22px] opacity-30 transition-all` } `} > {content.text}
- {!isAdd && + {/* {!isAdd && observe.boardId === boardId && observe.contentId === content.id && (
{`From: ${observe.writer}`}
- )} + )} */}
); }; diff --git a/src/recoil/observe.ts b/src/recoil/observe.ts index 30fd0fa8..b1fde28e 100644 --- a/src/recoil/observe.ts +++ b/src/recoil/observe.ts @@ -5,7 +5,7 @@ export const observeState = atom({ default: { boardId: 0, contentId: 0, - photo: '', + photoUrl: '', writer: '', }, }); From 113d3c77d3298e595d4611b305d18d2f0ae60a92 Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Fri, 24 Nov 2023 13:59:19 +0900 Subject: [PATCH 02/80] =?UTF-8?q?fix:=20writer=ED=83=9C=EA=B7=B8=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=ED=95=B4=EC=A0=9C=20#62?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/ObserveContent.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/component/ObserveContent.tsx b/src/component/ObserveContent.tsx index ced4a7df..ff86fa44 100644 --- a/src/component/ObserveContent.tsx +++ b/src/component/ObserveContent.tsx @@ -59,13 +59,13 @@ const ObserveContent = ({ content, boardId, isAdd }: props) => { > {content.text}
- {/* {!isAdd && + {!isAdd && observe.boardId === boardId && observe.contentId === content.id && (
{`From: ${observe.writer}`}
- )} */} + )} ); }; From 8a8ac75fa0e305540b3b6e148bd780f090cbb3b4 Mon Sep 17 00:00:00 2001 From: lamPolar Date: Fri, 24 Nov 2023 14:52:16 +0900 Subject: [PATCH 03/80] =?UTF-8?q?style=20:=20=EB=93=9C=EB=A1=9C=EC=96=B4?= =?UTF-8?q?=20=EC=9B=B9=20=EB=B7=B0=20=EC=9C=84=EC=B9=98=20=EC=9E=AC?= =?UTF-8?q?=EC=A7=80=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/layout.tsx | 6 +++--- src/app/page.tsx | 4 ++-- src/component/Drawer.tsx | 10 ++++++++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 195882d7..77f610e5 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -10,9 +10,9 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( - - -
+ + +
{children} diff --git a/src/app/page.tsx b/src/app/page.tsx index a7f2253f..07879b4b 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -7,7 +7,7 @@ import Link from 'next/link'; export default function Home() { return ( - <> +
@@ -49,6 +49,6 @@ export default function Home() { 를 누르면 여러 문자열을 한 그룹으로 관리할 수 있어요. 주렁주렁~
- +
); } diff --git a/src/component/Drawer.tsx b/src/component/Drawer.tsx index 73c71e45..5f7199df 100644 --- a/src/component/Drawer.tsx +++ b/src/component/Drawer.tsx @@ -38,10 +38,16 @@ export default function Drawer() { console.log(err); }); }, []); + const [, setDrawer] = useRecoilState(drawerState); + const handleBackground = (e: any) => { + console.log(e); + if (e.target !== e.currentTarget) return; + setDrawer(false); + }; return ( drawer && ( -
+
From 825894ebf81be33113f18d572e51d7f6dbdd7391 Mon Sep 17 00:00:00 2001 From: lamPolar Date: Fri, 24 Nov 2023 14:52:30 +0900 Subject: [PATCH 04/80] =?UTF-8?q?style=20:=20header=20profile=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/StrcatHeader.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/component/StrcatHeader.tsx b/src/component/StrcatHeader.tsx index 13798449..4a3c81ef 100644 --- a/src/component/StrcatHeader.tsx +++ b/src/component/StrcatHeader.tsx @@ -22,7 +22,7 @@ export default function StrcatHeader() { }, []); return ( -
+
logo From cf497f84bfa268280e3491e2dc93a260b4dfa4a0 Mon Sep 17 00:00:00 2001 From: lamPolar Date: Fri, 24 Nov 2023 15:02:52 +0900 Subject: [PATCH 05/80] =?UTF-8?q?feat=20:=20drawer=20=EC=9D=B4=EC=99=B8?= =?UTF-8?q?=EC=9D=98=20=EA=B3=B3=20=ED=81=B4=EB=A6=AD=EC=8B=9C=20=EC=82=AC?= =?UTF-8?q?=EC=9D=B4=EB=93=9C=EB=B0=94=20=EB=8B=AB=ED=9E=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/layout.tsx | 2 +- src/component/Drawer.tsx | 130 +++++++++++++++++++++------------------ 2 files changed, 70 insertions(+), 62 deletions(-) diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 77f610e5..e15dd672 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -12,7 +12,7 @@ export default function RootLayout({ return ( -
+
{children} diff --git a/src/component/Drawer.tsx b/src/component/Drawer.tsx index 5f7199df..6df68eb1 100644 --- a/src/component/Drawer.tsx +++ b/src/component/Drawer.tsx @@ -41,81 +41,89 @@ export default function Drawer() { const [, setDrawer] = useRecoilState(drawerState); const handleBackground = (e: any) => { - console.log(e); if (e.target !== e.currentTarget) return; setDrawer(false); }; return ( drawer && ( -
-
- profileImg -
-
-
- +
+
+
dropList setDropList(!dropList)} + src="/ProfileImg.svg" + width={72} + height={72} + alt="profileImg" + className="m-[24px]" />
- {dropList && ( -
- {personalList && ( - - )} -
- )} -
- - groupDropList setGroupDropList(!groupDropList)} - /> -
- {groupDropList && } -
-
+
+
-
-
- setDropList(!dropList)} />
-
+ {dropList && ( +
+ {personalList && ( + + )} +
+ )} +
+ groupDropList setGroupDropList(!groupDropList)} + /> +
+ {groupDropList && ( + + )} +
+
+ +
+
+ +
+
+ +
From 8740edbd6291f933844afe8f2fa27b6cbae74b51 Mon Sep 17 00:00:00 2001 From: lamPolar Date: Fri, 24 Nov 2023 15:04:22 +0900 Subject: [PATCH 06/80] =?UTF-8?q?refactor=20:=20event=20type=20=EC=A7=80?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/Drawer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/component/Drawer.tsx b/src/component/Drawer.tsx index 6df68eb1..e26dbf16 100644 --- a/src/component/Drawer.tsx +++ b/src/component/Drawer.tsx @@ -40,7 +40,7 @@ export default function Drawer() { }, []); const [, setDrawer] = useRecoilState(drawerState); - const handleBackground = (e: any) => { + const handleBackground = (e: React.MouseEvent) => { if (e.target !== e.currentTarget) return; setDrawer(false); }; From 122cb75a2218fd6b7687700ed09d1ed2d4a547fb Mon Sep 17 00:00:00 2001 From: lamPolar Date: Fri, 24 Nov 2023 15:07:12 +0900 Subject: [PATCH 07/80] =?UTF-8?q?style=20:=20drop=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=20=EC=98=81=EC=97=AD=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?&=20drop=EB=B2=84=ED=8A=BC=20=ED=91=9C=EC=8B=9C=20=EC=A1=B0?= =?UTF-8?q?=EA=B1=B4=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/Drawer.tsx | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/component/Drawer.tsx b/src/component/Drawer.tsx index e26dbf16..8cf85e33 100644 --- a/src/component/Drawer.tsx +++ b/src/component/Drawer.tsx @@ -61,20 +61,24 @@ export default function Drawer() { />
-
+
setDropList(!dropList)} + > - dropList setDropList(!dropList)} - /> + {personalList.length != 0 && ( + dropList + )}
{dropList && (
@@ -83,7 +87,10 @@ export default function Drawer() { )}
)} -
+
setGroupDropList(!groupDropList)} + > setGroupDropList(!groupDropList)} />
{groupDropList && ( From d1c4bcea2918a95abc0349ce8d40957de678c564 Mon Sep 17 00:00:00 2001 From: arkingco Date: Fri, 24 Nov 2023 15:11:50 +0900 Subject: [PATCH 08/80] =?UTF-8?q?feat:=20export=20=ED=85=8C=EB=A7=88=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EA=B5=AC=ED=98=84=20#20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/export/Default.tsx | 18 ++++++ src/app/export/ExportTheme.tsx | 23 ++++++++ src/app/export/LineBreak.tsx | 11 ++++ src/app/export/Writer.tsx | 16 ++++++ src/app/export/page.tsx | 101 +++++++++++++++++++++++++++++++++ 5 files changed, 169 insertions(+) create mode 100644 src/app/export/Default.tsx create mode 100644 src/app/export/ExportTheme.tsx create mode 100644 src/app/export/LineBreak.tsx create mode 100644 src/app/export/Writer.tsx create mode 100644 src/app/export/page.tsx diff --git a/src/app/export/Default.tsx b/src/app/export/Default.tsx new file mode 100644 index 00000000..3411da90 --- /dev/null +++ b/src/app/export/Default.tsx @@ -0,0 +1,18 @@ +'use client'; + +import { content } from '@/types/content'; + +interface Props { + content: content; +} +export default function Default({ content }: Props) { + return ( +
+ {content.id % 2 === 0 ? ( + {content.text} + ) : ( + {content.text} + )} +
+ ); +} diff --git a/src/app/export/ExportTheme.tsx b/src/app/export/ExportTheme.tsx new file mode 100644 index 00000000..4c515c51 --- /dev/null +++ b/src/app/export/ExportTheme.tsx @@ -0,0 +1,23 @@ +'use client'; +import { calm, cyan, green, strcat, themeState } from '@/recoil/theme'; +import { useRecoilState } from 'recoil'; +import Image from 'next/image'; + +interface Props { + name: string; + src: string; + alt: string; + onClick: () => void; +} +export default function ExportTheme({ name, src, alt, onClick }: Props) { + const [Theme, setTheme] = useRecoilState(themeState); + const handleThemeChange = (newTheme: themeState) => { + setTheme(newTheme); + }; + return ( +
+ {alt} +
{name}
+
+ ); +} diff --git a/src/app/export/LineBreak.tsx b/src/app/export/LineBreak.tsx new file mode 100644 index 00000000..24d93920 --- /dev/null +++ b/src/app/export/LineBreak.tsx @@ -0,0 +1,11 @@ +'use client'; + +import { content } from '@/types/content'; + +interface Props { + content: content; +} + +export default function LineBreak({ content }: Props) { + return
{`${content.text} From ${content.writer}`}
; +} diff --git a/src/app/export/Writer.tsx b/src/app/export/Writer.tsx new file mode 100644 index 00000000..acb3071f --- /dev/null +++ b/src/app/export/Writer.tsx @@ -0,0 +1,16 @@ +'use client'; + +import { content } from '@/types/content'; + +interface Props { + content: content; +} + +export default function Writer({ content }: Props) { + return ( +
+ {content.text} + {content.writer} +
+ ); +} diff --git a/src/app/export/page.tsx b/src/app/export/page.tsx new file mode 100644 index 00000000..ffeee1d0 --- /dev/null +++ b/src/app/export/page.tsx @@ -0,0 +1,101 @@ +'use client'; + +import Drawer from '@/component/Drawer'; +import StrcatHeader from '@/component/StrcatHeader'; +import ExportTheme from './ExportTheme'; +import { useEffect, useState } from 'react'; +import { content } from '@/types/content'; +import { axiosInstance } from '@/utils/axios'; +import BottomButton from '@/component/BottomButton'; +import Default from './Default'; +import Writer from './Writer'; +import LineBreak from './LineBreak'; + +const exportThemeEnum = { + default: 'default', + lineBreak: 'lineBreak', + writer: 'writer', +}; + +const exportThemeButton = [ + { + name: '기본', + src: '/strcatButton.png', + alt: 'strcatButton', + select: exportThemeEnum.default, + }, + { + name: '줄바꿈', + src: '/CalmButton.png', + alt: 'CalmButton', + select: exportThemeEnum.lineBreak, + }, + { + name: '작성자', + src: '/GreenButton.png', + alt: 'GreenButton', + select: exportThemeEnum.writer, + }, +]; + +export default function Export() { + const [title, setTitle] = useState(''); + const [data, setData] = useState(undefined); + const [exportTheme, setExportTheme] = useState( + exportThemeEnum.default, + ); + + useEffect(() => { + axiosInstance + .get(`/api/personal`) + .then((data) => { + setTitle(data.data.title); + setData(data.data.contents); + }) + .catch((error) => {}); + }, []); + + return ( +
+ + +
+
{title}
+
+ {data?.map((item: content) => ( + + {exportTheme === exportThemeEnum.default && ( + + )} + {exportTheme === exportThemeEnum.writer && ( + + )} + {exportTheme === exportThemeEnum.lineBreak && ( + + )} + + ))} +
+
+
+
+ {exportThemeButton.map((item) => ( + setExportTheme(item.select)} + /> + ))} +
+ console.log('hi')} + disabled={false} + /> +
+
+ ); +} From f0ac0277e0668a8bb294d90450291f04cac9e30d Mon Sep 17 00:00:00 2001 From: arkingco Date: Fri, 24 Nov 2023 15:14:34 +0900 Subject: [PATCH 09/80] =?UTF-8?q?feat:=20=EB=82=B4=EB=B3=B4=EB=82=B4?= =?UTF-8?q?=EA=B8=B0=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EB=8B=A4=EC=9A=B4=EB=A1=9C=EB=93=9C=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20#20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 45 +++++++++++++++++++++++++++++++++++++++++ package.json | 1 + src/app/export/page.tsx | 18 ++++++++++++++++- 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 8aa81945..ff283976 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.1.0", "dependencies": { "axios": "^1.6.0", + "html2canvas": "^1.4.1", "next": "13.5.6", "react": "^18", "react-dom": "^18", @@ -885,6 +886,14 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -1128,6 +1137,14 @@ "node": ">= 8" } }, + "node_modules/css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "dependencies": { + "utrie": "^1.0.2" + } + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -2312,6 +2329,18 @@ "node": ">= 0.4" } }, + "node_modules/html2canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "dependencies": { + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -4179,6 +4208,14 @@ "node": ">=6" } }, + "node_modules/text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "dependencies": { + "utrie": "^1.0.2" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -4421,6 +4458,14 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, + "node_modules/utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "dependencies": { + "base64-arraybuffer": "^1.0.2" + } + }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", diff --git a/package.json b/package.json index a883d218..b3ecbbe8 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "axios": "^1.6.0", + "html2canvas": "^1.4.1", "next": "13.5.6", "react": "^18", "react-dom": "^18", diff --git a/src/app/export/page.tsx b/src/app/export/page.tsx index ffeee1d0..3ff98065 100644 --- a/src/app/export/page.tsx +++ b/src/app/export/page.tsx @@ -10,6 +10,7 @@ import BottomButton from '@/component/BottomButton'; import Default from './Default'; import Writer from './Writer'; import LineBreak from './LineBreak'; +import html2canvas from 'html2canvas'; const exportThemeEnum = { default: 'default', @@ -55,6 +56,21 @@ export default function Export() { .catch((error) => {}); }, []); + const saveImageHandler = () => { + const target = document.getElementById('content'); + if (!target) { + return alert('결과 저장에 실패했습니다.'); + } + html2canvas(target).then((canvas) => { + const element = document.createElement('a'); + document.body.appendChild(element); + element.href = canvas.toDataURL('image/png'); + element.download = `strcat_${title}.png`; + element.click(); + document.body.removeChild(element); + }); + }; + return (
@@ -92,7 +108,7 @@ export default function Export() { name="저장하기" // w-full 안됨 왜?? width="w-[370px]" - onClickHandler={() => console.log('hi')} + onClickHandler={saveImageHandler} disabled={false} />
From 86609ac732cad9d80128927c6509206a3ade2401 Mon Sep 17 00:00:00 2001 From: lamPolar Date: Fri, 24 Nov 2023 15:24:37 +0900 Subject: [PATCH 10/80] =?UTF-8?q?feat=20:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EB=A1=9C=EB=94=A9=EC=86=8D=EB=8F=84=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/StrcatHeader.tsx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/component/StrcatHeader.tsx b/src/component/StrcatHeader.tsx index 4a3c81ef..8d278823 100644 --- a/src/component/StrcatHeader.tsx +++ b/src/component/StrcatHeader.tsx @@ -24,7 +24,14 @@ export default function StrcatHeader() { return (
- logo + logo
{isLogin ? ( @@ -33,6 +40,8 @@ export default function StrcatHeader() { width={40} height={10} alt="profileImg" + loading="eager" + priority onClick={() => setDrawer(true)} /> ) : ( @@ -43,7 +52,9 @@ export default function StrcatHeader() { width={74} height={34} alt="login" + loading="eager" className="absolute inset-0" + priority /> 로그인 From 2f4327100d1473d5002458bfb1f9037c7fb86397 Mon Sep 17 00:00:00 2001 From: arkingco Date: Fri, 24 Nov 2023 15:30:59 +0900 Subject: [PATCH 11/80] =?UTF-8?q?feat:=20=EC=8A=A4=ED=8A=B8=EB=A7=81?= =?UTF-8?q?=EC=BA=A3=20=EC=A0=80=EC=9E=A5=ED=95=98=EA=B8=B0=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20#20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 13 ++++++++ package.json | 2 ++ src/app/export/page.tsx | 43 +++++++++++++++++---------- src/component/Modal/ExportSuccess.tsx | 22 ++++++++++++++ 4 files changed, 64 insertions(+), 16 deletions(-) create mode 100644 src/component/Modal/ExportSuccess.tsx diff --git a/package-lock.json b/package-lock.json index ff283976..aa1313e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.1.0", "dependencies": { "axios": "^1.6.0", + "file-saver": "^2.0.5", "html2canvas": "^1.4.1", "next": "13.5.6", "react": "^18", @@ -16,6 +17,7 @@ "recoil": "^0.7.7" }, "devDependencies": { + "@types/file-saver": "^2.0.7", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", @@ -397,6 +399,12 @@ "tslib": "^2.4.0" } }, + "node_modules/@types/file-saver": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.7.tgz", + "integrity": "sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==", + "dev": true + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -1923,6 +1931,11 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", diff --git a/package.json b/package.json index b3ecbbe8..ec184a66 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "axios": "^1.6.0", + "file-saver": "^2.0.5", "html2canvas": "^1.4.1", "next": "13.5.6", "react": "^18", @@ -17,6 +18,7 @@ "recoil": "^0.7.7" }, "devDependencies": { + "@types/file-saver": "^2.0.7", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", diff --git a/src/app/export/page.tsx b/src/app/export/page.tsx index 3ff98065..dcb95bb7 100644 --- a/src/app/export/page.tsx +++ b/src/app/export/page.tsx @@ -3,7 +3,7 @@ import Drawer from '@/component/Drawer'; import StrcatHeader from '@/component/StrcatHeader'; import ExportTheme from './ExportTheme'; -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { content } from '@/types/content'; import { axiosInstance } from '@/utils/axios'; import BottomButton from '@/component/BottomButton'; @@ -11,6 +11,9 @@ import Default from './Default'; import Writer from './Writer'; import LineBreak from './LineBreak'; import html2canvas from 'html2canvas'; +import saveAs from 'file-saver'; +import useModal from '@/hooks/useModal'; +import ExportSuccess from '@/component/Modal/ExportSuccess'; const exportThemeEnum = { default: 'default', @@ -40,8 +43,10 @@ const exportThemeButton = [ ]; export default function Export() { + const [openModal, closeModal] = useModal(); const [title, setTitle] = useState(''); const [data, setData] = useState(undefined); + const divRef = useRef(null); const [exportTheme, setExportTheme] = useState( exportThemeEnum.default, ); @@ -56,26 +61,32 @@ export default function Export() { .catch((error) => {}); }, []); - const saveImageHandler = () => { - const target = document.getElementById('content'); - if (!target) { - return alert('결과 저장에 실패했습니다.'); + const handleSave = async () => { + if (!divRef.current) return; + try { + const div = divRef.current; + const canvas = await html2canvas(div, { scale: 2 }); + canvas.toBlob((blob) => { + if (blob !== null) { + saveAs(blob, `strcat_${title}.png`); + } + }); + openModal( + , + ); + } catch (error) { + console.error('Error converting div to image:', error); } - html2canvas(target).then((canvas) => { - const element = document.createElement('a'); - document.body.appendChild(element); - element.href = canvas.toDataURL('image/png'); - element.download = `strcat_${title}.png`; - element.click(); - document.body.removeChild(element); - }); }; return (
-
+
{title}
{data?.map((item: content) => ( @@ -94,7 +105,7 @@ export default function Export() {
-
+
{exportThemeButton.map((item) => (
diff --git a/src/component/Modal/ExportSuccess.tsx b/src/component/Modal/ExportSuccess.tsx new file mode 100644 index 00000000..479c27ab --- /dev/null +++ b/src/component/Modal/ExportSuccess.tsx @@ -0,0 +1,22 @@ +interface Props { + content: string; + handleModalClose: () => void; +} + +export default function Error({ content, handleModalClose }: Props) { + return ( +
+
+ {content} +
+
+ +
+
+ ); +} From 0775332c79b9de80024bd2e80296e4cb8d57c3de Mon Sep 17 00:00:00 2001 From: arkingco Date: Fri, 24 Nov 2023 15:33:06 +0900 Subject: [PATCH 12/80] =?UTF-8?q?fix:=20=ED=8F=B4=EB=8D=94=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95=20export=20->=20personal/id/expo?= =?UTF-8?q?rt=20#20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/{ => personal/[id]}/export/Default.tsx | 0 src/app/{ => personal/[id]}/export/ExportTheme.tsx | 0 src/app/{ => personal/[id]}/export/LineBreak.tsx | 0 src/app/{ => personal/[id]}/export/Writer.tsx | 0 src/app/{ => personal/[id]}/export/page.tsx | 1 + 5 files changed, 1 insertion(+) rename src/app/{ => personal/[id]}/export/Default.tsx (100%) rename src/app/{ => personal/[id]}/export/ExportTheme.tsx (100%) rename src/app/{ => personal/[id]}/export/LineBreak.tsx (100%) rename src/app/{ => personal/[id]}/export/Writer.tsx (100%) rename src/app/{ => personal/[id]}/export/page.tsx (99%) diff --git a/src/app/export/Default.tsx b/src/app/personal/[id]/export/Default.tsx similarity index 100% rename from src/app/export/Default.tsx rename to src/app/personal/[id]/export/Default.tsx diff --git a/src/app/export/ExportTheme.tsx b/src/app/personal/[id]/export/ExportTheme.tsx similarity index 100% rename from src/app/export/ExportTheme.tsx rename to src/app/personal/[id]/export/ExportTheme.tsx diff --git a/src/app/export/LineBreak.tsx b/src/app/personal/[id]/export/LineBreak.tsx similarity index 100% rename from src/app/export/LineBreak.tsx rename to src/app/personal/[id]/export/LineBreak.tsx diff --git a/src/app/export/Writer.tsx b/src/app/personal/[id]/export/Writer.tsx similarity index 100% rename from src/app/export/Writer.tsx rename to src/app/personal/[id]/export/Writer.tsx diff --git a/src/app/export/page.tsx b/src/app/personal/[id]/export/page.tsx similarity index 99% rename from src/app/export/page.tsx rename to src/app/personal/[id]/export/page.tsx index dcb95bb7..0e094853 100644 --- a/src/app/export/page.tsx +++ b/src/app/personal/[id]/export/page.tsx @@ -108,6 +108,7 @@ export default function Export() {
{exportThemeButton.map((item) => ( Date: Fri, 24 Nov 2023 15:38:53 +0900 Subject: [PATCH 13/80] =?UTF-8?q?refactor=20:=20=ED=95=84=EC=9A=94?= =?UTF-8?q?=EC=97=86=EB=8A=94=20div=20=EC=9D=98=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=EC=9D=BC=20=EC=98=B5=EC=85=98=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F?= =?UTF-8?q?=20div=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/page.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index 07879b4b..a7f2253f 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -7,7 +7,7 @@ import Link from 'next/link'; export default function Home() { return ( -
+ <>
@@ -49,6 +49,6 @@ export default function Home() { 를 누르면 여러 문자열을 한 그룹으로 관리할 수 있어요. 주렁주렁~
-
+ ); } From 1b2445dc8f86892595c5a925f45cf59fd7bc632f Mon Sep 17 00:00:00 2001 From: lamPolar Date: Fri, 24 Nov 2023 15:54:29 +0900 Subject: [PATCH 14/80] style: header image resize --- src/component/StrcatHeader.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/component/StrcatHeader.tsx b/src/component/StrcatHeader.tsx index 8d278823..5a5a7e2d 100644 --- a/src/component/StrcatHeader.tsx +++ b/src/component/StrcatHeader.tsx @@ -26,8 +26,8 @@ export default function StrcatHeader() { logo Date: Fri, 24 Nov 2023 16:15:36 +0900 Subject: [PATCH 15/80] =?UTF-8?q?feat:=20group=20export=20page=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20#20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/group/[id]/export/Board.tsx | 36 ++++++++ src/app/group/[id]/export/Default.tsx | 18 ++++ src/app/group/[id]/export/ExportTheme.tsx | 23 +++++ src/app/group/[id]/export/LineBreak.tsx | 11 +++ src/app/group/[id]/export/Writer.tsx | 16 ++++ src/app/group/[id]/export/page.tsx | 104 ++++++++++++++++++++++ src/app/personal/[id]/export/page.tsx | 30 +------ src/types/export.ts | 26 ++++++ 8 files changed, 236 insertions(+), 28 deletions(-) create mode 100644 src/app/group/[id]/export/Board.tsx create mode 100644 src/app/group/[id]/export/Default.tsx create mode 100644 src/app/group/[id]/export/ExportTheme.tsx create mode 100644 src/app/group/[id]/export/LineBreak.tsx create mode 100644 src/app/group/[id]/export/Writer.tsx create mode 100644 src/app/group/[id]/export/page.tsx create mode 100644 src/types/export.ts diff --git a/src/app/group/[id]/export/Board.tsx b/src/app/group/[id]/export/Board.tsx new file mode 100644 index 00000000..5dfff9d0 --- /dev/null +++ b/src/app/group/[id]/export/Board.tsx @@ -0,0 +1,36 @@ +import { content } from '@/types/content'; +import Default from './Default'; +import Writer from './Writer'; +import LineBreak from './LineBreak'; +import { exportThemeEnum } from '@/types/export'; + +interface Props { + title: string; + data: content[] | undefined; + exportTheme: string; +} + +export default function Board({ title, data, exportTheme }: Props) { + return ( +
+
+
{title}
+
+ {data?.map((item: content) => ( + + {exportTheme === exportThemeEnum.default && ( + + )} + {exportTheme === exportThemeEnum.writer && ( + + )} + {exportTheme === exportThemeEnum.lineBreak && ( + + )} + + ))} +
+
+
+ ); +} diff --git a/src/app/group/[id]/export/Default.tsx b/src/app/group/[id]/export/Default.tsx new file mode 100644 index 00000000..3411da90 --- /dev/null +++ b/src/app/group/[id]/export/Default.tsx @@ -0,0 +1,18 @@ +'use client'; + +import { content } from '@/types/content'; + +interface Props { + content: content; +} +export default function Default({ content }: Props) { + return ( +
+ {content.id % 2 === 0 ? ( + {content.text} + ) : ( + {content.text} + )} +
+ ); +} diff --git a/src/app/group/[id]/export/ExportTheme.tsx b/src/app/group/[id]/export/ExportTheme.tsx new file mode 100644 index 00000000..4c515c51 --- /dev/null +++ b/src/app/group/[id]/export/ExportTheme.tsx @@ -0,0 +1,23 @@ +'use client'; +import { calm, cyan, green, strcat, themeState } from '@/recoil/theme'; +import { useRecoilState } from 'recoil'; +import Image from 'next/image'; + +interface Props { + name: string; + src: string; + alt: string; + onClick: () => void; +} +export default function ExportTheme({ name, src, alt, onClick }: Props) { + const [Theme, setTheme] = useRecoilState(themeState); + const handleThemeChange = (newTheme: themeState) => { + setTheme(newTheme); + }; + return ( +
+ {alt} +
{name}
+
+ ); +} diff --git a/src/app/group/[id]/export/LineBreak.tsx b/src/app/group/[id]/export/LineBreak.tsx new file mode 100644 index 00000000..24d93920 --- /dev/null +++ b/src/app/group/[id]/export/LineBreak.tsx @@ -0,0 +1,11 @@ +'use client'; + +import { content } from '@/types/content'; + +interface Props { + content: content; +} + +export default function LineBreak({ content }: Props) { + return
{`${content.text} From ${content.writer}`}
; +} diff --git a/src/app/group/[id]/export/Writer.tsx b/src/app/group/[id]/export/Writer.tsx new file mode 100644 index 00000000..acb3071f --- /dev/null +++ b/src/app/group/[id]/export/Writer.tsx @@ -0,0 +1,16 @@ +'use client'; + +import { content } from '@/types/content'; + +interface Props { + content: content; +} + +export default function Writer({ content }: Props) { + return ( +
+ {content.text} + {content.writer} +
+ ); +} diff --git a/src/app/group/[id]/export/page.tsx b/src/app/group/[id]/export/page.tsx new file mode 100644 index 00000000..99c12a68 --- /dev/null +++ b/src/app/group/[id]/export/page.tsx @@ -0,0 +1,104 @@ +'use client'; + +import Drawer from '@/component/Drawer'; +import StrcatHeader from '@/component/StrcatHeader'; +import ExportTheme from './ExportTheme'; +import { useEffect, useRef, useState } from 'react'; +import { axiosInstance } from '@/utils/axios'; +import BottomButton from '@/component/BottomButton'; +import html2canvas from 'html2canvas'; +import saveAs from 'file-saver'; +import useModal from '@/hooks/useModal'; +import ExportSuccess from '@/component/Modal/ExportSuccess'; +import { board } from '@/types/boards'; +import Board from './Board'; +import { exportThemeButton, exportThemeEnum } from '@/types/export'; + +export default function Export() { + const divRef = useRef(null); + const [openModal, closeModal] = useModal(); + const [title, setTitle] = useState(''); + const [boardsTitle, setBoardsTitle] = useState([]); + const [boardsConetent, setBoardsContent] = useState([]); + const [exportTheme, setExportTheme] = useState( + exportThemeEnum.default, + ); + + useEffect(() => { + axiosInstance + .get(`/api/group`) + .then((data) => { + setTitle(data.data.titleData.title); + setBoardsTitle(data.data.titleData.boards); + setBoardsContent(data.data.contentData); + }) + .catch((error) => {}); + }, []); + + const handleSave = async () => { + if (!divRef.current) return; + try { + const div = divRef.current; + const canvas = await html2canvas(div, { scale: 2 }); + canvas.toBlob((blob) => { + if (blob !== null) { + saveAs(blob, `strcat_${title}.png`); + } + }); + openModal( + , + ); + } catch (error) { + console.error('Error converting div to image:', error); + } + }; + + return ( +
+ + +
+ {boardsTitle.map((board: board) => { + return ( +
+ {board.title} +
+ ); + })} + {boardsConetent.map((board) => { + return ( + + ); + })} +
+
+
+ {exportThemeButton.map((item) => ( + setExportTheme(item.select)} + /> + ))} +
+ +
+
+ ); +} diff --git a/src/app/personal/[id]/export/page.tsx b/src/app/personal/[id]/export/page.tsx index 0e094853..7f5fce1c 100644 --- a/src/app/personal/[id]/export/page.tsx +++ b/src/app/personal/[id]/export/page.tsx @@ -14,33 +14,7 @@ import html2canvas from 'html2canvas'; import saveAs from 'file-saver'; import useModal from '@/hooks/useModal'; import ExportSuccess from '@/component/Modal/ExportSuccess'; - -const exportThemeEnum = { - default: 'default', - lineBreak: 'lineBreak', - writer: 'writer', -}; - -const exportThemeButton = [ - { - name: '기본', - src: '/strcatButton.png', - alt: 'strcatButton', - select: exportThemeEnum.default, - }, - { - name: '줄바꿈', - src: '/CalmButton.png', - alt: 'CalmButton', - select: exportThemeEnum.lineBreak, - }, - { - name: '작성자', - src: '/GreenButton.png', - alt: 'GreenButton', - select: exportThemeEnum.writer, - }, -]; +import { exportThemeButton, exportThemeEnum } from '@/types/export'; export default function Export() { const [openModal, closeModal] = useModal(); @@ -88,7 +62,7 @@ export default function Export() {
{title}
-
+
{data?.map((item: content) => ( {exportTheme === exportThemeEnum.default && ( diff --git a/src/types/export.ts b/src/types/export.ts new file mode 100644 index 00000000..a22bcf12 --- /dev/null +++ b/src/types/export.ts @@ -0,0 +1,26 @@ +export const exportThemeEnum = { + default: 'default', + lineBreak: 'lineBreak', + writer: 'writer', +}; + +export const exportThemeButton = [ + { + name: '기본', + src: '/strcatButton.png', + alt: 'strcatButton', + select: exportThemeEnum.default, + }, + { + name: '줄바꿈', + src: '/CalmButton.png', + alt: 'CalmButton', + select: exportThemeEnum.lineBreak, + }, + { + name: '작성자', + src: '/GreenButton.png', + alt: 'GreenButton', + select: exportThemeEnum.writer, + }, +]; From 5841078559db81f94a73b9c251d74e0f1715e8cd Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Fri, 24 Nov 2023 16:24:39 +0900 Subject: [PATCH 16/80] =?UTF-8?q?feat:=20=EA=B7=B8=EB=A3=B9=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EA=B8=80=EC=9E=91=EC=84=B1=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/group/[id]/page.tsx | 21 ++++++++++++++++++++- src/app/personal/[id]/page.tsx | 5 ++--- src/component/ObserveContent.tsx | 4 ++-- src/component/StrcatBoard.tsx | 15 +++++++++++---- 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/app/group/[id]/page.tsx b/src/app/group/[id]/page.tsx index dc1e4c1a..4a545a22 100644 --- a/src/app/group/[id]/page.tsx +++ b/src/app/group/[id]/page.tsx @@ -9,6 +9,9 @@ import { useRecoilState } from 'recoil'; import { themeState } from '@/recoil/theme'; import Drawer from '@/component/Drawer'; import StrcatHeader from '@/component/StrcatHeader'; +import Add from '@/component/Add'; +import BottomButton from '@/component/BottomButton'; +import { observeState } from '@/recoil/observe'; export default function Home() { const [title, setTitle] = useState(); @@ -17,12 +20,16 @@ export default function Home() { const [isAdd, setIsAdd] = useState(false); const [theme] = useRecoilState(themeState); const itemsRef = useRef(new Map()); + const [observe] = useRecoilState(observeState); const scrollToId = (itemId: number) => { const map = getMap(); const node = map.get(itemId); const offset = node.offsetTop; window.scrollTo({ top: offset, behavior: 'smooth' }); }; + const handleClick = () => { + setIsAdd(true); + }; const getMap = () => { return itemsRef.current; }; @@ -65,6 +72,7 @@ export default function Home() { {boardsConetent.map((board) => { return ( { const map = getMap(); @@ -82,7 +90,18 @@ export default function Home() { ); })}
- + {!isAdd && ( +
+ +
+ )} + {!isAdd && } + {!isAdd && }
); diff --git a/src/app/personal/[id]/page.tsx b/src/app/personal/[id]/page.tsx index b75be3d0..234851a9 100644 --- a/src/app/personal/[id]/page.tsx +++ b/src/app/personal/[id]/page.tsx @@ -68,10 +68,9 @@ export default function Home() { title={title} data={data} isAdd={isAdd} + setIsAdd={setIsAdd} /> - {isAdd ? ( - - ) : ( + {!isAdd && (
{ (entries) => { entries.forEach(({ isIntersecting, boundingClientRect }) => { ratio = 10 / boundingClientRect.height; - if (isIntersecting) { + if (!isAdd && isIntersecting) { setObserve(() => ({ boardId: boardId, contentId: content.id, @@ -41,7 +41,7 @@ const ObserveContent = ({ content, boardId, isAdd }: props) => { return () => { observer.disconnect(); }; - }, [boardId, content.id, content.photo, content.writer, setObserve]); + }, [boardId, content.id, content.photo, content.writer, setObserve, isAdd]); return (
diff --git a/src/component/StrcatBoard.tsx b/src/component/StrcatBoard.tsx index 519a0f9b..eed4d400 100644 --- a/src/component/StrcatBoard.tsx +++ b/src/component/StrcatBoard.tsx @@ -1,22 +1,26 @@ import { content } from '@/types/content'; import ObserveContent from './ObserveContent'; -import { forwardRef } from 'react'; +import { forwardRef, Dispatch, SetStateAction } from 'react'; import React from 'react'; import { useRecoilState } from 'recoil'; import { themeState } from '@/recoil/theme'; +import Add from './Add'; +import { observeState } from '@/recoil/observe'; -interface props { +interface Props { title: string; data: content[] | undefined; boardId: number; isAdd: boolean; + setIsAdd: Dispatch>; } -const StrcatBoard = forwardRef(function StrcatBoard( - { title, data, boardId, isAdd }, +const StrcatBoard = forwardRef(function StrcatBoard( + { title, data, boardId, isAdd, setIsAdd }, ref, ) { const [theme] = useRecoilState(themeState); + const [observe] = useRecoilState(observeState); return (
@@ -35,6 +39,9 @@ const StrcatBoard = forwardRef(function StrcatBoard( ); })}
+ {isAdd && boardId === observe.boardId && ( + + )} {!isAdd &&
}
); From f31bb24ebb84d769947800d06c951ad9cef3581d Mon Sep 17 00:00:00 2001 From: arkingco Date: Fri, 24 Nov 2023 16:27:25 +0900 Subject: [PATCH 17/80] =?UTF-8?q?refactor:=20=EA=B7=B8=EB=A3=B9,=20?= =?UTF-8?q?=EA=B0=9C=EB=B3=84=20=EB=82=B4=EB=B3=B4=EB=82=B4=EA=B8=B0=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=ED=86=B5=ED=95=A9=20#20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/group/[id]/export/ExportTheme.tsx | 6 +--- src/app/group/[id]/export/page.tsx | 5 ++- src/app/personal/[id]/export/Default.tsx | 18 ---------- src/app/personal/[id]/export/LineBreak.tsx | 11 ------ src/app/personal/[id]/export/Writer.tsx | 16 --------- src/app/personal/[id]/export/page.tsx | 35 ++++++------------- .../[id] => component}/export/Default.tsx | 0 .../export/ExportBoard.tsx} | 2 +- .../[id] => component}/export/ExportTheme.tsx | 6 +--- .../[id] => component}/export/LineBreak.tsx | 0 .../[id] => component}/export/Writer.tsx | 0 11 files changed, 16 insertions(+), 83 deletions(-) delete mode 100644 src/app/personal/[id]/export/Default.tsx delete mode 100644 src/app/personal/[id]/export/LineBreak.tsx delete mode 100644 src/app/personal/[id]/export/Writer.tsx rename src/{app/group/[id] => component}/export/Default.tsx (100%) rename src/{app/group/[id]/export/Board.tsx => component/export/ExportBoard.tsx} (92%) rename src/{app/personal/[id] => component}/export/ExportTheme.tsx (66%) rename src/{app/group/[id] => component}/export/LineBreak.tsx (100%) rename src/{app/group/[id] => component}/export/Writer.tsx (100%) diff --git a/src/app/group/[id]/export/ExportTheme.tsx b/src/app/group/[id]/export/ExportTheme.tsx index 4c515c51..09af1e4c 100644 --- a/src/app/group/[id]/export/ExportTheme.tsx +++ b/src/app/group/[id]/export/ExportTheme.tsx @@ -10,14 +10,10 @@ interface Props { onClick: () => void; } export default function ExportTheme({ name, src, alt, onClick }: Props) { - const [Theme, setTheme] = useRecoilState(themeState); - const handleThemeChange = (newTheme: themeState) => { - setTheme(newTheme); - }; return (
{alt} -
{name}
+
{name}
); } diff --git a/src/app/group/[id]/export/page.tsx b/src/app/group/[id]/export/page.tsx index 99c12a68..119ae28e 100644 --- a/src/app/group/[id]/export/page.tsx +++ b/src/app/group/[id]/export/page.tsx @@ -11,8 +11,8 @@ import saveAs from 'file-saver'; import useModal from '@/hooks/useModal'; import ExportSuccess from '@/component/Modal/ExportSuccess'; import { board } from '@/types/boards'; -import Board from './Board'; import { exportThemeButton, exportThemeEnum } from '@/types/export'; +import ExportBoard from '@/component/export/ExportBoard'; export default function Export() { const divRef = useRef(null); @@ -70,7 +70,7 @@ export default function Export() { })} {boardsConetent.map((board) => { return ( - - {content.id % 2 === 0 ? ( - {content.text} - ) : ( - {content.text} - )} -
- ); -} diff --git a/src/app/personal/[id]/export/LineBreak.tsx b/src/app/personal/[id]/export/LineBreak.tsx deleted file mode 100644 index 24d93920..00000000 --- a/src/app/personal/[id]/export/LineBreak.tsx +++ /dev/null @@ -1,11 +0,0 @@ -'use client'; - -import { content } from '@/types/content'; - -interface Props { - content: content; -} - -export default function LineBreak({ content }: Props) { - return
{`${content.text} From ${content.writer}`}
; -} diff --git a/src/app/personal/[id]/export/Writer.tsx b/src/app/personal/[id]/export/Writer.tsx deleted file mode 100644 index acb3071f..00000000 --- a/src/app/personal/[id]/export/Writer.tsx +++ /dev/null @@ -1,16 +0,0 @@ -'use client'; - -import { content } from '@/types/content'; - -interface Props { - content: content; -} - -export default function Writer({ content }: Props) { - return ( -
- {content.text} - {content.writer} -
- ); -} diff --git a/src/app/personal/[id]/export/page.tsx b/src/app/personal/[id]/export/page.tsx index 7f5fce1c..c866d0eb 100644 --- a/src/app/personal/[id]/export/page.tsx +++ b/src/app/personal/[id]/export/page.tsx @@ -2,24 +2,22 @@ import Drawer from '@/component/Drawer'; import StrcatHeader from '@/component/StrcatHeader'; -import ExportTheme from './ExportTheme'; import { useEffect, useRef, useState } from 'react'; import { content } from '@/types/content'; import { axiosInstance } from '@/utils/axios'; import BottomButton from '@/component/BottomButton'; -import Default from './Default'; -import Writer from './Writer'; -import LineBreak from './LineBreak'; import html2canvas from 'html2canvas'; import saveAs from 'file-saver'; import useModal from '@/hooks/useModal'; import ExportSuccess from '@/component/Modal/ExportSuccess'; import { exportThemeButton, exportThemeEnum } from '@/types/export'; +import ExportBoard from '@/component/export/ExportBoard'; +import ExportTheme from '../../../../component/export/ExportTheme'; export default function Export() { const [openModal, closeModal] = useModal(); const [title, setTitle] = useState(''); - const [data, setData] = useState(undefined); + const [board, setBoard] = useState(undefined); const divRef = useRef(null); const [exportTheme, setExportTheme] = useState( exportThemeEnum.default, @@ -30,7 +28,7 @@ export default function Export() { .get(`/api/personal`) .then((data) => { setTitle(data.data.title); - setData(data.data.contents); + setBoard(data.data.contents); }) .catch((error) => {}); }, []); @@ -61,22 +59,12 @@ export default function Export() {
-
{title}
-
- {data?.map((item: content) => ( - - {exportTheme === exportThemeEnum.default && ( - - )} - {exportTheme === exportThemeEnum.writer && ( - - )} - {exportTheme === exportThemeEnum.lineBreak && ( - - )} - - ))} -
+
@@ -92,8 +80,7 @@ export default function Export() {
diff --git a/src/app/group/[id]/export/Default.tsx b/src/component/export/Default.tsx similarity index 100% rename from src/app/group/[id]/export/Default.tsx rename to src/component/export/Default.tsx diff --git a/src/app/group/[id]/export/Board.tsx b/src/component/export/ExportBoard.tsx similarity index 92% rename from src/app/group/[id]/export/Board.tsx rename to src/component/export/ExportBoard.tsx index 5dfff9d0..57ff82d0 100644 --- a/src/app/group/[id]/export/Board.tsx +++ b/src/component/export/ExportBoard.tsx @@ -10,7 +10,7 @@ interface Props { exportTheme: string; } -export default function Board({ title, data, exportTheme }: Props) { +export default function ExportBoard({ title, data, exportTheme }: Props) { return (
diff --git a/src/app/personal/[id]/export/ExportTheme.tsx b/src/component/export/ExportTheme.tsx similarity index 66% rename from src/app/personal/[id]/export/ExportTheme.tsx rename to src/component/export/ExportTheme.tsx index 4c515c51..09af1e4c 100644 --- a/src/app/personal/[id]/export/ExportTheme.tsx +++ b/src/component/export/ExportTheme.tsx @@ -10,14 +10,10 @@ interface Props { onClick: () => void; } export default function ExportTheme({ name, src, alt, onClick }: Props) { - const [Theme, setTheme] = useRecoilState(themeState); - const handleThemeChange = (newTheme: themeState) => { - setTheme(newTheme); - }; return (
{alt} -
{name}
+
{name}
); } diff --git a/src/app/group/[id]/export/LineBreak.tsx b/src/component/export/LineBreak.tsx similarity index 100% rename from src/app/group/[id]/export/LineBreak.tsx rename to src/component/export/LineBreak.tsx diff --git a/src/app/group/[id]/export/Writer.tsx b/src/component/export/Writer.tsx similarity index 100% rename from src/app/group/[id]/export/Writer.tsx rename to src/component/export/Writer.tsx From a76f3a4fce3479c9a40eedbf0263597ef29e6ca1 Mon Sep 17 00:00:00 2001 From: arkingco Date: Fri, 24 Nov 2023 16:31:18 +0900 Subject: [PATCH 18/80] =?UTF-8?q?refactor:=20import=20=EC=88=9C=EC=84=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20group=20ExportBoard=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=ED=86=B5=ED=95=A9=20#20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/group/[id]/export/ExportTheme.tsx | 19 ------------------- src/app/group/[id]/export/page.tsx | 14 +++++++------- src/app/personal/[id]/export/page.tsx | 12 ++++++------ 3 files changed, 13 insertions(+), 32 deletions(-) delete mode 100644 src/app/group/[id]/export/ExportTheme.tsx diff --git a/src/app/group/[id]/export/ExportTheme.tsx b/src/app/group/[id]/export/ExportTheme.tsx deleted file mode 100644 index 09af1e4c..00000000 --- a/src/app/group/[id]/export/ExportTheme.tsx +++ /dev/null @@ -1,19 +0,0 @@ -'use client'; -import { calm, cyan, green, strcat, themeState } from '@/recoil/theme'; -import { useRecoilState } from 'recoil'; -import Image from 'next/image'; - -interface Props { - name: string; - src: string; - alt: string; - onClick: () => void; -} -export default function ExportTheme({ name, src, alt, onClick }: Props) { - return ( -
- {alt} -
{name}
-
- ); -} diff --git a/src/app/group/[id]/export/page.tsx b/src/app/group/[id]/export/page.tsx index 119ae28e..5d2fd5ad 100644 --- a/src/app/group/[id]/export/page.tsx +++ b/src/app/group/[id]/export/page.tsx @@ -1,18 +1,18 @@ 'use client'; -import Drawer from '@/component/Drawer'; -import StrcatHeader from '@/component/StrcatHeader'; -import ExportTheme from './ExportTheme'; import { useEffect, useRef, useState } from 'react'; +import { board } from '@/types/boards'; +import { exportThemeButton, exportThemeEnum } from '@/types/export'; import { axiosInstance } from '@/utils/axios'; -import BottomButton from '@/component/BottomButton'; import html2canvas from 'html2canvas'; import saveAs from 'file-saver'; -import useModal from '@/hooks/useModal'; +import BottomButton from '@/component/BottomButton'; import ExportSuccess from '@/component/Modal/ExportSuccess'; -import { board } from '@/types/boards'; -import { exportThemeButton, exportThemeEnum } from '@/types/export'; +import Drawer from '@/component/Drawer'; +import StrcatHeader from '@/component/StrcatHeader'; import ExportBoard from '@/component/export/ExportBoard'; +import ExportTheme from '@/component/export/ExportTheme'; +import useModal from '@/hooks/useModal'; export default function Export() { const divRef = useRef(null); diff --git a/src/app/personal/[id]/export/page.tsx b/src/app/personal/[id]/export/page.tsx index c866d0eb..ba0158c4 100644 --- a/src/app/personal/[id]/export/page.tsx +++ b/src/app/personal/[id]/export/page.tsx @@ -1,18 +1,18 @@ 'use client'; -import Drawer from '@/component/Drawer'; -import StrcatHeader from '@/component/StrcatHeader'; import { useEffect, useRef, useState } from 'react'; import { content } from '@/types/content'; +import { exportThemeButton, exportThemeEnum } from '@/types/export'; import { axiosInstance } from '@/utils/axios'; -import BottomButton from '@/component/BottomButton'; import html2canvas from 'html2canvas'; import saveAs from 'file-saver'; -import useModal from '@/hooks/useModal'; +import BottomButton from '@/component/BottomButton'; import ExportSuccess from '@/component/Modal/ExportSuccess'; -import { exportThemeButton, exportThemeEnum } from '@/types/export'; import ExportBoard from '@/component/export/ExportBoard'; -import ExportTheme from '../../../../component/export/ExportTheme'; +import Drawer from '@/component/Drawer'; +import StrcatHeader from '@/component/StrcatHeader'; +import ExportTheme from '@/component/export/ExportTheme'; +import useModal from '@/hooks/useModal'; export default function Export() { const [openModal, closeModal] = useModal(); From 84604a114110bd828724c72080c60f0fa72238f8 Mon Sep 17 00:00:00 2001 From: arkingco Date: Fri, 24 Nov 2023 16:45:10 +0900 Subject: [PATCH 19/80] =?UTF-8?q?fix:=20=EB=AA=A8=EB=8B=AC=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EB=B3=80=EA=B2=BD#20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/Modal/ExportSuccess.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/component/Modal/ExportSuccess.tsx b/src/component/Modal/ExportSuccess.tsx index 479c27ab..e493e73a 100644 --- a/src/component/Modal/ExportSuccess.tsx +++ b/src/component/Modal/ExportSuccess.tsx @@ -3,7 +3,7 @@ interface Props { handleModalClose: () => void; } -export default function Error({ content, handleModalClose }: Props) { +export default function ExportSuccess({ content, handleModalClose }: Props) { return (
From 3a3106a746000c66e25029bf1c468bcbe93a8d15 Mon Sep 17 00:00:00 2001 From: dokoh Date: Fri, 24 Nov 2023 16:49:51 +0900 Subject: [PATCH 20/80] =?UTF-8?q?feat/mainpage=20=EB=94=94=EC=9E=90?= =?UTF-8?q?=EC=9D=B8=20=EC=A0=81=EC=9A=A9#63?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/GroupStrcatMake.png | Bin 0 -> 253 bytes public/StrcatMake.png | Bin 0 -> 250 bytes public/strcatImage.png | Bin 24476 -> 15375 bytes src/app/page.tsx | 98 +++++++++++++++++++++++-------------- tailwind.config.js | 12 ++++- 5 files changed, 70 insertions(+), 40 deletions(-) create mode 100644 public/GroupStrcatMake.png create mode 100644 public/StrcatMake.png diff --git a/public/GroupStrcatMake.png b/public/GroupStrcatMake.png new file mode 100644 index 0000000000000000000000000000000000000000..ea8c97542a170967b9eb6f6ddda7bba36f98eef5 GIT binary patch literal 253 zcmeAS@N?(olHy`uVBq!ia0vp^CxBR$gAGWsH!V8^q&N#aB8wRqxP?KOkzv*x37{Zj zage(c!@6@aFM%AEbVpxD28NCO+w)uIHjF-aGkqZ!)pHieBm$M*Jcgf*BRtESq^=PI%v$zFVdQ&MBb@0LL;tMgRZ+ literal 0 HcmV?d00001 diff --git a/public/StrcatMake.png b/public/StrcatMake.png new file mode 100644 index 0000000000000000000000000000000000000000..f7dd18295d25002baa1d49ab3cf7715cfeaa8cb8 GIT binary patch literal 250 zcmeAS@N?(olHy`uVBq!ia0vp^(|}l&gAGV7h!?N~Qk(@Ik;M!Q+`=Ht$S`Y;1W=H% zILO_JVcj{Imp~3nx}&cn1H;CC?mvmFKz_fci(^Oy;JW|740 znb9yop>fyV@=WHb_lx&zE8fdi^Tb?1K}YB^_mYH-9vs~*8z?9Ku-9b7_x+6Nc6EwS dX>onTwqJwo8*}J#1EA9wJYD@<);T3K0RRv4QD^`F literal 0 HcmV?d00001 diff --git a/public/strcatImage.png b/public/strcatImage.png index 70ee9bcae530e6c86d2920921fd8474dbd7dbffe..f76690bc0bf462b7f03ceb762ee6622648f8180f 100644 GIT binary patch literal 15375 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 diff --git a/src/app/page.tsx b/src/app/page.tsx index a7f2253f..d863a3d6 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -2,53 +2,75 @@ import Drawer from '@/component/Drawer'; import StrcatHeader from '@/component/StrcatHeader'; -import Link from 'next/link'; -// import Image from 'next/image'; +import Image from 'next/image'; +import { useRouter } from 'next/navigation'; export default function Home() { + const router = useRouter(); + const handleClick = () => { + router.push('/create'); + }; return ( - <> +
-
-
-
-
{`//`}
-
스트링캣
-
-
-
-
- 스트링캣은 문자열을 끝없이 늘려 스크롤을 만들 수 있는 신개념 +
+
+ Image +
+

+ // 스트링캣은 문자열을 끝없이 늘려 스크롤을 만들 수 있는 신개념 롤링페이퍼 서비스 입니다. -

-
소중한 사람에게 스트링캣을 남겨보세요!
+

+

소중한 사람에게 스트링캣을 남겨보세요!

-
- {/* strcatImage */} -
-
- - 스트링캣 만들기 - - 를 누르면 하나의 문자열을 할당받을 수 있어요. 링크를 공유해 문자열을 - 끝없이 이어보세요. +
+
+
+ button +
+ 스트링캣 만들기 +
+
+
+ 를 누르면 하나의 문자열을 할당받을 수 있어요. 링크를 공유해 + 문자열을 끝없이 이어보세요. +
+
-
- - - 그룹 스트링캣 만들기 - - - 를 누르면 여러 문자열을 한 그룹으로 관리할 수 있어요. 주렁주렁~ +
+
+
+ button +
+ 그룹 스트링캣 만들기 +
+
+
+  를 누르면 여러 문자열을 한 그룹으로 관리할 수 있어요. + 주렁주렁~ +
+
- +
); } diff --git a/tailwind.config.js b/tailwind.config.js index 80d7ced0..c2274a4f 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -10,11 +10,19 @@ module.exports = { ], theme: { extend: { + fontSize: { + xxl: [ + '1.35rem', + { + lineHeight: '2.25rem', + }, + ], + }, colors: { 'strcat-white': '#F0EEEA', 'strcat-black': '#212121', 'strcat-green': '#7CED43', - 'strcat-blue': '#557FE4', + 'strcat-blue': '#6CD8ED', 'strcat-yellow': '#FBFF36', 'strcat-buttonColor': '#8F38FF', }, @@ -32,6 +40,6 @@ module.exports = { sans: ['Noto Sans KR', 'DotGothic16'], FiraCode: ['FiraCode'], }, + plugins: [], }, - plugins: [], }; From 4876fb9f2b82d1b77a44e70f38829c89e27c7679 Mon Sep 17 00:00:00 2001 From: dokoh Date: Fri, 24 Nov 2023 17:58:54 +0900 Subject: [PATCH 21/80] =?UTF-8?q?feat/summary=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20css=20=EA=B5=AC=ED=98=84#69?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/summary/page.tsx | 75 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/app/summary/page.tsx diff --git a/src/app/summary/page.tsx b/src/app/summary/page.tsx new file mode 100644 index 00000000..f25c59eb --- /dev/null +++ b/src/app/summary/page.tsx @@ -0,0 +1,75 @@ +'use client'; + +import { themeState } from '@/recoil/theme'; +import Image from 'next/image'; +import Link from 'next/link'; +import { useRecoilState } from 'recoil'; +import ThemeChange from '@/component/ThemeChange'; +import { axiosInstance } from '@/utils/axios'; +import { useParams } from 'next/navigation'; +import { useEffect, useState } from 'react'; + +export default function Home() { + const [Theme, setTheme] = useRecoilState(themeState); + const params = useParams(); + const [Title, setTitle] = useState( + '테스트 제목입니다. 테스트 제목입니다. 테스트 제목입니다.', + ); + const [ContentCount, setContentCount] = useState('13'); + const [ContentTextCount, setContentTextCount] = useState('1305'); + + // useEffect(() => { + // axiosInstance + // .get(`/boards/${params.id}/summaries`) + // .then((data) => { + // setTitle(data.data.title); + // setContentCount(data.data.contentCount); + // setContentTextCount(data.data.contentTextCount); + // setTheme(data.data.theme); + // }) + // .catch((err) => { + // if (err.response.status === 406) { + // alert('올바르지 않은 입력입니다. 다시 작성해주세요.'); + // } + // }); + // }, []); + + return ( +
+ Image +
+ 총 {ContentCount}번의
마음으로
내 스트링캣이
총{' '} + {ContentTextCount}자
이어졌어요! +
+
+
+
+ + backpagebutton + +
+
+ 스트링캣 공유하기 +
+
+
+
{Title}
+
+ ); +} From 274481f9ebfdf18da0f6e4320564f40ba6acf66b Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Fri, 24 Nov 2023 18:26:45 +0900 Subject: [PATCH 22/80] =?UTF-8?q?feat:=20observe=EC=95=88=EB=90=90?= =?UTF-8?q?=EC=9D=84=EB=95=8C=20=EA=B8=80=EC=9E=91=EC=84=B1=20disable?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/group/[id]/page.tsx | 5 ++--- src/app/personal/[id]/page.tsx | 7 ++++--- src/component/Add.tsx | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/app/group/[id]/page.tsx b/src/app/group/[id]/page.tsx index 4a545a22..5660824c 100644 --- a/src/app/group/[id]/page.tsx +++ b/src/app/group/[id]/page.tsx @@ -68,7 +68,7 @@ export default function Home() { ); })}
-
+
{boardsConetent.map((board) => { return (
)} {!isAdd && } - {!isAdd && }
); diff --git a/src/app/personal/[id]/page.tsx b/src/app/personal/[id]/page.tsx index 234851a9..b5c14a60 100644 --- a/src/app/personal/[id]/page.tsx +++ b/src/app/personal/[id]/page.tsx @@ -9,9 +9,9 @@ import BottomButton from '@/component/BottomButton'; import ContentPhoto from '@/component/ContentPhoto'; import { useRecoilState } from 'recoil'; import { themeState } from '@/recoil/theme'; -import { useParams } from 'next/navigation'; import Drawer from '@/component/Drawer'; import StrcatHeader from '@/component/StrcatHeader'; +import { observeState } from '@/recoil/observe'; export default function Home() { const [title, setTitle] = useState(''); @@ -20,7 +20,8 @@ export default function Home() { const [isAdd, setIsAdd] = useState(false); const [theme] = useRecoilState(themeState); const itemsRef = useRef(new Map()); - const params = useParams(); + const [observe] = useRecoilState(observeState); + const scrollToId = (itemId: number) => { const map = getMap(); const node = map.get(itemId); @@ -76,7 +77,7 @@ export default function Home() { name="글 작성" width="w-full" onClickHandler={handleClick} - disabled={false} + disabled={!observe.boardId} />
)} diff --git a/src/component/Add.tsx b/src/component/Add.tsx index b9d51724..7b3eca82 100644 --- a/src/component/Add.tsx +++ b/src/component/Add.tsx @@ -42,7 +42,7 @@ export default function Add({ id, setIsAdd }: AddProps) { }; axiosInstance - .post(`/boards/${id}/contents`, data) + .post(`/board/${id}/content`, data) .then((res) => { console.log(res); }) @@ -121,7 +121,7 @@ export default function Add({ id, setIsAdd }: AddProps) {
-
+
Date: Fri, 24 Nov 2023 18:34:34 +0900 Subject: [PATCH 23/80] =?UTF-8?q?feat:=20useAxiosInterceptor=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84#70?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/error/data.json | 67 ++++++++++++++++++++++++++++++ src/app/api/error/route.ts | 6 +++ src/app/layout.tsx | 4 +- src/app/modal/page.tsx | 11 +++++ src/component/AxiosInterceptor.tsx | 6 +++ src/hooks/useInterceptor.tsx | 37 +++++++++++++++++ src/utils/axios.ts | 5 --- 7 files changed, 130 insertions(+), 6 deletions(-) create mode 100644 src/app/api/error/data.json create mode 100644 src/app/api/error/route.ts create mode 100644 src/component/AxiosInterceptor.tsx create mode 100644 src/hooks/useInterceptor.tsx diff --git a/src/app/api/error/data.json b/src/app/api/error/data.json new file mode 100644 index 00000000..2260b818 --- /dev/null +++ b/src/app/api/error/data.json @@ -0,0 +1,67 @@ +{ + "id": 1, + "title": "Sample Board", + "backgroundColor": "#ffffff", + "contents": [ + { + "id": 1, + "text": "즐거운 순간을 함께하며 행복한 기억 만들기를 기대해요.n", + "writer": "영일이삼사오육칠팔구", + "photo": "/Google.png" + }, + { + "id": 2, + "text": "봄바람 속에 햇살이 미소 짓도록. 따뜻한 날 되세요.", + "writer": "User2", + "photo": "/kakao.png" + }, + { + "id": 3, + "text": "마음 가는 대로 꿈 펼쳐보세요. 가능성은 무한합니다.", + "writer": "User3", + "photo": "/strcatImage.png" + }, + { + "id": 4, + "text": "지친 하루 뒤에 찾아오는 평화로운 밤 되길 바랍니다.", + "writer": "User4", + "photo": "/mario.png" + }, + { + "id": 5, + "text": "소소한 행복에 감사하며 강한 마음으로 살아갑시다.", + "writer": "User5", + "photo": "" + }, + { + "id": 6, + "text": "작은 기쁨이 큰 행복을 만들어냅니다. 즐거운 순간들!", + "writer": "User6", + "photo": "/Google.png" + }, + { + "id": 7, + "text": "마음 가는 대로 여유롭게 휴식 취하며 힐링하세요.", + "writer": "User7", + "photo": "/kakao.png" + }, + { + "id": 8, + "text": "간만에 소중한 사람들과 얼굴 마주하는 특별한 순간.", + "writer": "User8", + "photo": "" + }, + { + "id": 9, + "text": "어제보다 나은 오늘을 만들어가며 행복한 하루 되세요.", + "writer": "User10", + "photo": "" + }, + { + "id": 10, + "text": "사용자 여러분 안녕하세요! 여러분의 호기심과 질문을 받아서 항상 즐거운 시간을 보내고 있습니다. 여러분이 무엇이든지 물어보고 학습하려는 모습은 정말 멋지고 영감을 주는 일이에요. 또한 여러분이 공유하는 이야기와 고민들은 모두 소중하게 여기고 있습니다. 우리는 모두 다른 경험과 배경을 가지고 있지만, 이 작은 공간에서 우리는 서로에게 도움이 되고 함께 성장하는 커뮤니티를 이룰 수 있습니다. 함께 배우고 나누며, 서로에게 격려와 지지를 주고 받으면서 더 나은 개인과 더 나은 세상을 만들어 나갈 수 있을 것입니다. 계속해서 궁금한 점이나 이야기를 나누어 주세요. 여러분의 참여는 이 커뮤니티를 더욱 풍요롭게 만들어 줍니다. 감사합니다. 함께 여행하는 동안 뜻깊은 순간들이 많아지길 기대하고 있어요! 😊✨", + "writer": "User10", + "photo": "" + } + ] +} diff --git a/src/app/api/error/route.ts b/src/app/api/error/route.ts new file mode 100644 index 00000000..02d37906 --- /dev/null +++ b/src/app/api/error/route.ts @@ -0,0 +1,6 @@ +import { NextResponse } from 'next/server'; +import data from './data.json'; + +export async function GET(request: any) { + return NextResponse.json(data, { status: 500 }); +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 195882d7..c2c51633 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -3,6 +3,7 @@ import { RecoilRoot } from 'recoil'; import './globals.css'; import Modal from '@/component/Modal'; +import AxiosInterceptor from '@/component/AxiosInterceptor'; export default function RootLayout({ children, @@ -12,8 +13,9 @@ export default function RootLayout({ return ( -
+
+ {children} diff --git a/src/app/modal/page.tsx b/src/app/modal/page.tsx index cad4da58..f66e03f8 100644 --- a/src/app/modal/page.tsx +++ b/src/app/modal/page.tsx @@ -5,6 +5,7 @@ import Error from '@/component/Modal/Error'; import useModal from '@/hooks/useModal'; import { catState } from '@/recoil/cat'; import { catAction } from '@/types/cat'; +import { axiosInstance } from '@/utils/axios'; import { confirm } from '@/utils/confirm'; import { useRecoilState } from 'recoil'; @@ -64,6 +65,13 @@ export default function Modal() { }); }; + const handleErrorRespons = () => { + axiosInstance + .get('/api/error') + .then((res) => {}) + .catch((error) => {}); + }; + return (
@@ -82,6 +90,9 @@ export default function Modal() {
+
+ +
); } diff --git a/src/component/AxiosInterceptor.tsx b/src/component/AxiosInterceptor.tsx new file mode 100644 index 00000000..a6ef76ff --- /dev/null +++ b/src/component/AxiosInterceptor.tsx @@ -0,0 +1,6 @@ +import { useInterceptor } from '@/hooks/useInterceptor'; + +export default function AxiosInterceptor() { + useInterceptor(); + return <>; +} diff --git a/src/hooks/useInterceptor.tsx b/src/hooks/useInterceptor.tsx new file mode 100644 index 00000000..40e3e366 --- /dev/null +++ b/src/hooks/useInterceptor.tsx @@ -0,0 +1,37 @@ +import { axiosInstance } from '@/utils/axios'; +import { useEffect } from 'react'; +import useModal from './useModal'; +import Error from '@/component/Modal/Error'; + +export const useInterceptor = () => { + const [openModal, closeModal] = useModal(); + const responseHandler = (response: any) => { + return response; + }; + const requestHandler = async (config: any) => { + config.withCredentials = true; + return config; + }; + + const errorHandler = (errorStatus: number) => { + if (errorStatus === 401 || errorStatus === 500) { + openModal( + , + ); + } + }; + + const requestInterceptor = + axiosInstance.interceptors.request.use(requestHandler); + const responseInterceptor = axiosInstance.interceptors.response.use( + (response) => responseHandler(response), + (error) => errorHandler(error.response.status), + ); + + useEffect(() => { + return () => { + axiosInstance.interceptors.request.eject(requestInterceptor); + axiosInstance.interceptors.response.eject(responseInterceptor); + }; + }, [responseInterceptor, requestInterceptor]); +}; diff --git a/src/utils/axios.ts b/src/utils/axios.ts index 403c913d..8167cb80 100644 --- a/src/utils/axios.ts +++ b/src/utils/axios.ts @@ -1,7 +1,2 @@ import axios from 'axios'; export const axiosInstance = axios.create(); - -axiosInstance.interceptors.request.use(function setConfig(config) { - config.withCredentials = true; - return config; -}); From 2cc8cc295fe9070e363439254f628783659e2cc8 Mon Sep 17 00:00:00 2001 From: arkingco Date: Fri, 24 Nov 2023 18:40:04 +0900 Subject: [PATCH 24/80] =?UTF-8?q?fix:=20api=20data=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?#70?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/error/data.json | 66 +------------------------------------ 1 file changed, 1 insertion(+), 65 deletions(-) diff --git a/src/app/api/error/data.json b/src/app/api/error/data.json index 2260b818..f63dea53 100644 --- a/src/app/api/error/data.json +++ b/src/app/api/error/data.json @@ -1,67 +1,3 @@ { - "id": 1, - "title": "Sample Board", - "backgroundColor": "#ffffff", - "contents": [ - { - "id": 1, - "text": "즐거운 순간을 함께하며 행복한 기억 만들기를 기대해요.n", - "writer": "영일이삼사오육칠팔구", - "photo": "/Google.png" - }, - { - "id": 2, - "text": "봄바람 속에 햇살이 미소 짓도록. 따뜻한 날 되세요.", - "writer": "User2", - "photo": "/kakao.png" - }, - { - "id": 3, - "text": "마음 가는 대로 꿈 펼쳐보세요. 가능성은 무한합니다.", - "writer": "User3", - "photo": "/strcatImage.png" - }, - { - "id": 4, - "text": "지친 하루 뒤에 찾아오는 평화로운 밤 되길 바랍니다.", - "writer": "User4", - "photo": "/mario.png" - }, - { - "id": 5, - "text": "소소한 행복에 감사하며 강한 마음으로 살아갑시다.", - "writer": "User5", - "photo": "" - }, - { - "id": 6, - "text": "작은 기쁨이 큰 행복을 만들어냅니다. 즐거운 순간들!", - "writer": "User6", - "photo": "/Google.png" - }, - { - "id": 7, - "text": "마음 가는 대로 여유롭게 휴식 취하며 힐링하세요.", - "writer": "User7", - "photo": "/kakao.png" - }, - { - "id": 8, - "text": "간만에 소중한 사람들과 얼굴 마주하는 특별한 순간.", - "writer": "User8", - "photo": "" - }, - { - "id": 9, - "text": "어제보다 나은 오늘을 만들어가며 행복한 하루 되세요.", - "writer": "User10", - "photo": "" - }, - { - "id": 10, - "text": "사용자 여러분 안녕하세요! 여러분의 호기심과 질문을 받아서 항상 즐거운 시간을 보내고 있습니다. 여러분이 무엇이든지 물어보고 학습하려는 모습은 정말 멋지고 영감을 주는 일이에요. 또한 여러분이 공유하는 이야기와 고민들은 모두 소중하게 여기고 있습니다. 우리는 모두 다른 경험과 배경을 가지고 있지만, 이 작은 공간에서 우리는 서로에게 도움이 되고 함께 성장하는 커뮤니티를 이룰 수 있습니다. 함께 배우고 나누며, 서로에게 격려와 지지를 주고 받으면서 더 나은 개인과 더 나은 세상을 만들어 나갈 수 있을 것입니다. 계속해서 궁금한 점이나 이야기를 나누어 주세요. 여러분의 참여는 이 커뮤니티를 더욱 풍요롭게 만들어 줍니다. 감사합니다. 함께 여행하는 동안 뜻깊은 순간들이 많아지길 기대하고 있어요! 😊✨", - "writer": "User10", - "photo": "" - } - ] + "title": "Error" } From 4364b36a29438783e1349f61547e94e727a30dbd Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Fri, 24 Nov 2023 21:28:19 +0900 Subject: [PATCH 25/80] =?UTF-8?q?feat:=20bottombutton=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=EC=9D=BC=EC=A0=81=EC=9A=A9=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/group/[id]/page.tsx | 26 ++++++++++++++++++++++++-- src/app/personal/[id]/page.tsx | 21 +++++++++++++++++++-- src/component/BottomButton.tsx | 14 +++++++++++++- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/app/group/[id]/page.tsx b/src/app/group/[id]/page.tsx index 5660824c..6ad3a56d 100644 --- a/src/app/group/[id]/page.tsx +++ b/src/app/group/[id]/page.tsx @@ -91,10 +91,32 @@ export default function Home() { })}
{!isAdd && ( -
+
+ + + diff --git a/src/app/personal/[id]/page.tsx b/src/app/personal/[id]/page.tsx index b5c14a60..0754b84a 100644 --- a/src/app/personal/[id]/page.tsx +++ b/src/app/personal/[id]/page.tsx @@ -12,6 +12,7 @@ import { themeState } from '@/recoil/theme'; import Drawer from '@/component/Drawer'; import StrcatHeader from '@/component/StrcatHeader'; import { observeState } from '@/recoil/observe'; +import { useRouter } from 'next/navigation'; export default function Home() { const [title, setTitle] = useState(''); @@ -21,6 +22,7 @@ export default function Home() { const [theme] = useRecoilState(themeState); const itemsRef = useRef(new Map()); const [observe] = useRecoilState(observeState); + const router = useRouter(); const scrollToId = (itemId: number) => { const map = getMap(); @@ -72,12 +74,27 @@ export default function Home() { setIsAdd={setIsAdd} /> {!isAdd && ( -
+
+ router.push('./export')} + disabled={false} + color={`bg-white`} + /> + router.push('./summary')} + disabled={false} + color={`bg-[#7CED43]`} + />
)} diff --git a/src/component/BottomButton.tsx b/src/component/BottomButton.tsx index 47f24b60..22371c6f 100644 --- a/src/component/BottomButton.tsx +++ b/src/component/BottomButton.tsx @@ -1,8 +1,12 @@ +import { themeState } from '@/recoil/theme'; +import { useRecoilState } from 'recoil'; + interface BottomButtonProps { name: string; width: string; onClickHandler: () => void; disabled: boolean; + color: string; } export default function BottomButton({ @@ -10,13 +14,21 @@ export default function BottomButton({ width, onClickHandler, disabled, + color, }: BottomButtonProps) { + const [theme] = useRecoilState(themeState); return ( ); From 958e80dfb658bdcfc9b3f8622eee70f3adfb9c6f Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Sat, 25 Nov 2023 01:40:33 +0900 Subject: [PATCH 26/80] =?UTF-8?q?feat:=20grouppage=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/group/data.json | 24 +++++---------------- src/app/api/personal/data.json | 4 ++-- src/app/group/[id]/page.tsx | 30 +++++++++++++------------- src/app/personal/[id]/page.tsx | 37 +++++++++++++++++--------------- src/component/Add.tsx | 2 ++ src/component/ObserveContent.tsx | 12 +++++------ src/component/StrcatBoard.tsx | 19 ++++++++++------ src/recoil/theme.ts | 7 ++++++ src/types/boards.ts | 2 +- tailwind.config.js | 1 + 10 files changed, 72 insertions(+), 66 deletions(-) diff --git a/src/app/api/group/data.json b/src/app/api/group/data.json index ba8eb799..2ec1eb08 100644 --- a/src/app/api/group/data.json +++ b/src/app/api/group/data.json @@ -1,25 +1,11 @@ { - "titleData": { - "title": "친애하는 친구에게", - "backgroundColor": "#FFDAB9", - "boards": [ - { - "id": 1, - "title": "소중한 인연을 지켜줘", - "backgroundColor": "#87CEEB" - }, - { - "id": 2, - "title": "감사의 마음을 전해줘", - "backgroundColor": "#90EE90" - } - ] - }, - "contentData": [ + "isOwner": true, + "title": "hello~~", + "boards": [ { "id": 1, "title": "소중한 인연을 지켜줘", - "backgroundColor": "#87CEEB", + "theme": "calm", "content": [ { "id": 1, @@ -44,7 +30,7 @@ { "id": 2, "title": "감사의 마음을 전해줘", - "backgroundColor": "#90EE90", + "theme": "green", "content": [ { "id": 4, diff --git a/src/app/api/personal/data.json b/src/app/api/personal/data.json index 2260b818..ced634cc 100644 --- a/src/app/api/personal/data.json +++ b/src/app/api/personal/data.json @@ -1,8 +1,8 @@ { "id": 1, "title": "Sample Board", - "backgroundColor": "#ffffff", - "contents": [ + "theme": "green", + "content": [ { "id": 1, "text": "즐거운 순간을 함께하며 행복한 기억 만들기를 기대해요.n", diff --git a/src/app/group/[id]/page.tsx b/src/app/group/[id]/page.tsx index 6ad3a56d..6091722a 100644 --- a/src/app/group/[id]/page.tsx +++ b/src/app/group/[id]/page.tsx @@ -6,17 +6,15 @@ import StrcatBoard from '@/component/StrcatBoard'; import { board } from '@/types/boards'; import ContentPhoto from '@/component/ContentPhoto'; import { useRecoilState } from 'recoil'; -import { themeState } from '@/recoil/theme'; +import { themeObj, themeState } from '@/recoil/theme'; import Drawer from '@/component/Drawer'; import StrcatHeader from '@/component/StrcatHeader'; -import Add from '@/component/Add'; import BottomButton from '@/component/BottomButton'; import { observeState } from '@/recoil/observe'; export default function Home() { const [title, setTitle] = useState(); - const [boardsTitle, setBoardsTitle] = useState([]); - const [boardsConetent, setBoardsContent] = useState([]); + const [boards, setBoards] = useState([]); const [isAdd, setIsAdd] = useState(false); const [theme] = useRecoilState(themeState); const itemsRef = useRef(new Map()); @@ -37,9 +35,8 @@ export default function Home() { axiosInstance .get(`/api/group`) .then((data) => { - setTitle(data.data.titleData.title); - setBoardsTitle(data.data.titleData.boards); - setBoardsContent(data.data.contentData); + setBoards(data.data.boards); + setTitle(data.data.title); }) .catch((error) => {}); }, []); @@ -47,20 +44,22 @@ export default function Home() { <> -
+

{title}

- {boardsTitle.map((board: board) => { + {boards.map((board: board) => { return (
scrollToId(board.id)} >

{board.title}

@@ -69,11 +68,12 @@ export default function Home() { })}
- {boardsConetent.map((board) => { + {boards.map((board) => { return ( { const map = getMap(); if (node) { @@ -107,14 +107,14 @@ export default function Home() { disabled={false} /> (''); - const [boardId, setBoardId] = useState(0); - const [data, setData] = useState(undefined); + const [boards, setBoards] = useState({ + id: 0, + title: '', + theme: 'strcat', + content: [], + }); const [isAdd, setIsAdd] = useState(false); - const [theme] = useRecoilState(themeState); const itemsRef = useRef(new Map()); const [observe] = useRecoilState(observeState); const router = useRouter(); @@ -37,11 +40,8 @@ export default function Home() { useEffect(() => { axiosInstance .get(`/api/personal`) - //.get(`/boards/${params.id}/contents`) .then((data) => { - setBoardId(data.data.id); - setTitle(data.data.title); - setData(data.data.contents); + setBoards(data.data); }) .catch((error) => {}); }, []); @@ -56,20 +56,23 @@ export default function Home() {
{ const map = getMap(); if (node) { - map.set(boardId, node); + map.set(boards.id, node); } else { - map.delete(boardId); + map.delete(boards.id); } }} - boardId={boardId} - title={title} - data={data} + boardId={boards.id} + title={boards.title} + data={boards.content} isAdd={isAdd} setIsAdd={setIsAdd} /> @@ -87,14 +90,14 @@ export default function Home() { width="basis-1/5" onClickHandler={() => router.push('./summary')} disabled={false} - color={`bg-[#7CED43]`} + color={`bg-strcat-green`} />
)} diff --git a/src/component/Add.tsx b/src/component/Add.tsx index 7b3eca82..f33c818e 100644 --- a/src/component/Add.tsx +++ b/src/component/Add.tsx @@ -123,6 +123,7 @@ export default function Add({ id, setIsAdd }: AddProps) {
setIsAdd(false)} @@ -153,6 +154,7 @@ export default function Add({ id, setIsAdd }: AddProps) { )} { +const ObserveContent = ({ content, boardId, isAdd, theme }: props) => { const ref = useRef(null); const [observe, setObserve] = useRecoilState(observeState); - const [theme] = useRecoilState(themeState); useEffect(() => { let ratio = 0.01; const observer = new IntersectionObserver( @@ -52,8 +52,8 @@ const ObserveContent = ({ content, boardId, isAdd }: props) => { !isAdd && observe.boardId === boardId && observe.contentId === content.id - ? `${theme.FontColor1} ' duration-500' inline w-full text-[22px] opacity-100 transition-all` - : `${theme.DefaultFontColor} ' duration-500' inline w-full text-[22px] opacity-30 transition-all` + ? `${themeObj[theme].FontColor1} ' duration-500' inline w-full text-[22px] opacity-100 transition-all` + : `${themeObj[theme].DefaultFontColor} ' duration-500' inline w-full text-[22px] opacity-30 transition-all` } `} > @@ -63,7 +63,7 @@ const ObserveContent = ({ content, boardId, isAdd }: props) => { observe.boardId === boardId && observe.contentId === content.id && (
{`From: ${observe.writer}`}
)}
diff --git a/src/component/StrcatBoard.tsx b/src/component/StrcatBoard.tsx index eed4d400..92c00301 100644 --- a/src/component/StrcatBoard.tsx +++ b/src/component/StrcatBoard.tsx @@ -1,9 +1,9 @@ import { content } from '@/types/content'; import ObserveContent from './ObserveContent'; -import { forwardRef, Dispatch, SetStateAction } from 'react'; +import { forwardRef, Dispatch, SetStateAction, useState } from 'react'; import React from 'react'; import { useRecoilState } from 'recoil'; -import { themeState } from '@/recoil/theme'; +import { themeObj } from '@/recoil/theme'; import Add from './Add'; import { observeState } from '@/recoil/observe'; @@ -13,18 +13,24 @@ interface Props { boardId: number; isAdd: boolean; setIsAdd: Dispatch>; + theme: 'strcat' | 'calm' | 'green' | 'cyan'; } const StrcatBoard = forwardRef(function StrcatBoard( - { title, data, boardId, isAdd, setIsAdd }, + { title, data, boardId, isAdd, setIsAdd, theme }, ref, ) { - const [theme] = useRecoilState(themeState); const [observe] = useRecoilState(observeState); + return ( -
+
-

{title}

+

+ {title} +

{data && @@ -35,6 +41,7 @@ const StrcatBoard = forwardRef(function StrcatBoard( key={content.id} content={content} boardId={boardId} + theme={theme} /> ); })} diff --git a/src/recoil/theme.ts b/src/recoil/theme.ts index 1deb1b5a..513e673e 100644 --- a/src/recoil/theme.ts +++ b/src/recoil/theme.ts @@ -37,6 +37,13 @@ export const cyan: themeState = { BgColor: 'bg-strcat-black', }; +export const themeObj = { + strcat: strcat, + calm: calm, + green: green, + cyan: cyan, +}; + export const themeState = atom({ key: 'themeState', default: strcat, diff --git a/src/types/boards.ts b/src/types/boards.ts index a878077b..eb971108 100644 --- a/src/types/boards.ts +++ b/src/types/boards.ts @@ -3,6 +3,6 @@ import { content } from './content'; export interface board { id: number; title: string; - backgroundColor: string; + theme: 'strcat' | 'calm' | 'green' | 'cyan'; content: content[]; } diff --git a/tailwind.config.js b/tailwind.config.js index 80d7ced0..64d84ad6 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -16,6 +16,7 @@ module.exports = { 'strcat-green': '#7CED43', 'strcat-blue': '#557FE4', 'strcat-yellow': '#FBFF36', + 'strcat-cyan': '#6CD8ED', 'strcat-buttonColor': '#8F38FF', }, keyframes: { From ae3180c02129fe67071b101f8f5f4283cb64e403 Mon Sep 17 00:00:00 2001 From: arkingco Date: Sat, 25 Nov 2023 02:53:39 +0900 Subject: [PATCH 27/80] =?UTF-8?q?feat:=20strcat=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=EB=B3=84=20=EC=83=89=EC=83=81=20tailwind=20=EC=A0=81=EC=9A=A9#?= =?UTF-8?q?72?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tailwind.config.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tailwind.config.js b/tailwind.config.js index 80d7ced0..8b4c8ae9 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -17,6 +17,34 @@ module.exports = { 'strcat-blue': '#557FE4', 'strcat-yellow': '#FBFF36', 'strcat-buttonColor': '#8F38FF', + + 'strcat-default-yellow': '#FBFF36', + 'strcat-default-cyan': '#6CD8ED', + 'strcat-default-green': '#7CD43', + 'strcat-default-magenta': '#FF43A8', + 'strcat-default-white': '#FFFFFF', + 'strcat-default-black': '#212121', + + 'strcat-calm-orange': '#FFA857', + 'strcat-calm-cyan': '#ABC4FF', + 'strcat-calm-text-cyan': '567FE4', + 'strcat-calm-green': '#BEE4A4', + 'strcat-calm-text-green': '#61A136', + 'strcat-calm-magenta': '#FF43A8', + 'strcat-calm-white': '#F0EEEA', + 'strcat-calm-black': '#463F3A', + + 'strcat-green-black': '#212121', + 'strcat-green-cyan': '#8CD8ED', + 'strcat-green-yellow': '#FBFF36', + 'strcat-green-green': '#7CED43', + + 'strcat-cyan-white': '#FFFFFF', + 'strcat-cyan-green': '#7CED43', + 'strcat-cyan-yellow': '#FBFF36', + 'strcat-cyan-magenta': '#FF43A8', + 'strcat-cyan-cyan': '#6CD8ED', + 'strcat-cyan-black': '#212121', }, keyframes: { slide: { From 547b581d3830815a810f03930754fe1494d59f04 Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Sat, 25 Nov 2023 11:13:31 +0900 Subject: [PATCH 28/80] =?UTF-8?q?style:=20group=20title=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EB=B6=84=EB=A6=AC=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/group/[id]/page.tsx | 17 +++++------------ src/component/StrcatGroupTitle.tsx | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 src/component/StrcatGroupTitle.tsx diff --git a/src/app/group/[id]/page.tsx b/src/app/group/[id]/page.tsx index 6091722a..afc378e0 100644 --- a/src/app/group/[id]/page.tsx +++ b/src/app/group/[id]/page.tsx @@ -11,6 +11,7 @@ import Drawer from '@/component/Drawer'; import StrcatHeader from '@/component/StrcatHeader'; import BottomButton from '@/component/BottomButton'; import { observeState } from '@/recoil/observe'; +import StrcatGroupTitle from '@/component/StrcatGroupTitle'; export default function Home() { const [title, setTitle] = useState(); @@ -51,19 +52,11 @@ export default function Home() {
{boards.map((board: board) => { return ( -
scrollToId(board.id)} - > -

- {board.title} -

-
+ board={board} + scrollToId={scrollToId} + /> ); })}
diff --git a/src/component/StrcatGroupTitle.tsx b/src/component/StrcatGroupTitle.tsx new file mode 100644 index 00000000..05b5ed4d --- /dev/null +++ b/src/component/StrcatGroupTitle.tsx @@ -0,0 +1,25 @@ +import { themeObj } from '@/recoil/theme'; +import { board } from '@/types/boards'; + +interface Props { + board: board; + scrollToId: (arg0: number) => void; +} + +export default function StrcatGroupTitle({ board, scrollToId }: Props) { + return ( +
scrollToId(board.id)} + > +

+ {board.title} +

+
+ ); +} From 254fc15f804ab97a2cffde8fe03b2995c740a790 Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Sat, 25 Nov 2023 11:23:07 +0900 Subject: [PATCH 29/80] =?UTF-8?q?style:=20group=20-=20strcat=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20props=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/group/[id]/page.tsx | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/app/group/[id]/page.tsx b/src/app/group/[id]/page.tsx index afc378e0..1c1c10a2 100644 --- a/src/app/group/[id]/page.tsx +++ b/src/app/group/[id]/page.tsx @@ -32,6 +32,14 @@ export default function Home() { const getMap = () => { return itemsRef.current; }; + const setMap = (node: HTMLDivElement | null, board: board) => { + const map = getMap(); + if (node) { + map.set(board.id, node); + } else { + map.delete(board.id); + } + }; useEffect(() => { axiosInstance .get(`/api/group`) @@ -67,14 +75,7 @@ export default function Home() { theme={board.theme} setIsAdd={setIsAdd} isAdd={isAdd} - ref={(node) => { - const map = getMap(); - if (node) { - map.set(board.id, node); - } else { - map.delete(board.id); - } - }} + ref={(node) => setMap(node, board)} key={board.id} boardId={board.id} title={board.title} From 64cddaaaf643e20f075c60b83d6878057c6323c3 Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Sat, 25 Nov 2023 11:29:40 +0900 Subject: [PATCH 30/80] =?UTF-8?q?style:=20StrcatBoard=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20props=EC=A0=95=EB=A6=AC=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/group/[id]/page.tsx | 7 ++----- src/component/StrcatBoard.tsx | 26 +++++++++++++------------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/app/group/[id]/page.tsx b/src/app/group/[id]/page.tsx index 1c1c10a2..0941daf4 100644 --- a/src/app/group/[id]/page.tsx +++ b/src/app/group/[id]/page.tsx @@ -6,7 +6,7 @@ import StrcatBoard from '@/component/StrcatBoard'; import { board } from '@/types/boards'; import ContentPhoto from '@/component/ContentPhoto'; import { useRecoilState } from 'recoil'; -import { themeObj, themeState } from '@/recoil/theme'; +import { themeState } from '@/recoil/theme'; import Drawer from '@/component/Drawer'; import StrcatHeader from '@/component/StrcatHeader'; import BottomButton from '@/component/BottomButton'; @@ -72,14 +72,11 @@ export default function Home() { {boards.map((board) => { return ( setMap(node, board)} key={board.id} - boardId={board.id} - title={board.title} - data={board.content} + board={board} /> ); })} diff --git a/src/component/StrcatBoard.tsx b/src/component/StrcatBoard.tsx index 92c00301..cd39ce98 100644 --- a/src/component/StrcatBoard.tsx +++ b/src/component/StrcatBoard.tsx @@ -6,18 +6,16 @@ import { useRecoilState } from 'recoil'; import { themeObj } from '@/recoil/theme'; import Add from './Add'; import { observeState } from '@/recoil/observe'; +import { board } from '@/types/boards'; interface Props { - title: string; - data: content[] | undefined; - boardId: number; + board: board; isAdd: boolean; setIsAdd: Dispatch>; - theme: 'strcat' | 'calm' | 'green' | 'cyan'; } const StrcatBoard = forwardRef(function StrcatBoard( - { title, data, boardId, isAdd, setIsAdd, theme }, + { board, isAdd, setIsAdd }, ref, ) { const [observe] = useRecoilState(observeState); @@ -25,28 +23,30 @@ const StrcatBoard = forwardRef(function StrcatBoard( return (
-

- {title} +

+ {board.title}

- {data && - data.map((content: content) => { + {board.content && + board.content.map((content: content) => { return ( ); })}
- {isAdd && boardId === observe.boardId && ( + {isAdd && board.id === observe.boardId && ( )} {!isAdd &&
} From 031ece0474b48126ca30b8b9b5517f2b3f520755 Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Sat, 25 Nov 2023 12:35:53 +0900 Subject: [PATCH 31/80] =?UTF-8?q?style:=20=EC=A4=91=EB=B3=B5=EB=90=98?= =?UTF-8?q?=EB=8A=94=20=ED=95=A8=EC=88=98=20util=EB=A1=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/group/[id]/page.tsx | 17 ++++----------- src/app/personal/[id]/page.tsx | 38 +++++++--------------------------- src/utils/scrollTo.ts | 26 +++++++++++++++++++++++ 3 files changed, 38 insertions(+), 43 deletions(-) create mode 100644 src/utils/scrollTo.ts diff --git a/src/app/group/[id]/page.tsx b/src/app/group/[id]/page.tsx index 0941daf4..07c00f9e 100644 --- a/src/app/group/[id]/page.tsx +++ b/src/app/group/[id]/page.tsx @@ -12,6 +12,7 @@ import StrcatHeader from '@/component/StrcatHeader'; import BottomButton from '@/component/BottomButton'; import { observeState } from '@/recoil/observe'; import StrcatGroupTitle from '@/component/StrcatGroupTitle'; +import { scrollToAdd, setMap } from '@/utils/scrollTo'; export default function Home() { const [title, setTitle] = useState(); @@ -21,24 +22,14 @@ export default function Home() { const itemsRef = useRef(new Map()); const [observe] = useRecoilState(observeState); const scrollToId = (itemId: number) => { - const map = getMap(); + const map = itemsRef.current; const node = map.get(itemId); const offset = node.offsetTop; window.scrollTo({ top: offset, behavior: 'smooth' }); }; const handleClick = () => { setIsAdd(true); - }; - const getMap = () => { - return itemsRef.current; - }; - const setMap = (node: HTMLDivElement | null, board: board) => { - const map = getMap(); - if (node) { - map.set(board.id, node); - } else { - map.delete(board.id); - } + scrollToAdd(observe.boardId, itemsRef); }; useEffect(() => { axiosInstance @@ -74,7 +65,7 @@ export default function Home() { setMap(node, board)} + ref={(node) => setMap(node, board, itemsRef)} key={board.id} board={board} /> diff --git a/src/app/personal/[id]/page.tsx b/src/app/personal/[id]/page.tsx index 6b0fac32..927cb581 100644 --- a/src/app/personal/[id]/page.tsx +++ b/src/app/personal/[id]/page.tsx @@ -2,21 +2,20 @@ import { useEffect, useRef, useState } from 'react'; import { axiosInstance } from '@/utils/axios'; -import { content } from '@/types/content'; import StrcatBoard from '@/component/StrcatBoard'; -import Add from '@/component/Add'; import BottomButton from '@/component/BottomButton'; import ContentPhoto from '@/component/ContentPhoto'; import { useRecoilState } from 'recoil'; -import { themeObj, themeState } from '@/recoil/theme'; +import { themeObj } from '@/recoil/theme'; import Drawer from '@/component/Drawer'; import StrcatHeader from '@/component/StrcatHeader'; import { observeState } from '@/recoil/observe'; import { useRouter } from 'next/navigation'; import { board } from '@/types/boards'; +import { scrollToAdd, setMap } from '@/utils/scrollTo'; export default function Home() { - const [boards, setBoards] = useState({ + const [board, setBoard] = useState({ id: 0, title: '', theme: 'strcat', @@ -26,29 +25,18 @@ export default function Home() { const itemsRef = useRef(new Map()); const [observe] = useRecoilState(observeState); const router = useRouter(); - - const scrollToId = (itemId: number) => { - const map = getMap(); - const node = map.get(itemId); - const height = node.offsetHeight; - const offset = node.offsetTop + height - 500; // 하단의 여백을 500만큼 줬으므로 그만큼 빼준다. - window.scrollTo({ top: offset, behavior: 'smooth' }); - }; - const getMap = () => { - return itemsRef.current; - }; useEffect(() => { axiosInstance .get(`/api/personal`) .then((data) => { - setBoards(data.data); + setBoard(data.data); }) .catch((error) => {}); }, []); const handleClick = () => { setIsAdd(true); - scrollToId(boardId); + scrollToAdd(board.id, itemsRef); }; return ( @@ -57,22 +45,12 @@ export default function Home() {
{ - const map = getMap(); - if (node) { - map.set(boards.id, node); - } else { - map.delete(boards.id); - } - }} - boardId={boards.id} - title={boards.title} - data={boards.content} + board={board} + ref={(node) => setMap(node, board, itemsRef)} isAdd={isAdd} setIsAdd={setIsAdd} /> diff --git a/src/utils/scrollTo.ts b/src/utils/scrollTo.ts new file mode 100644 index 00000000..5887c63d --- /dev/null +++ b/src/utils/scrollTo.ts @@ -0,0 +1,26 @@ +import { MutableRefObject } from 'react'; +import { board } from '@/types/boards'; + +export const scrollToAdd = ( + itemId: number, + itemsRef: MutableRefObject>, +) => { + const map = itemsRef.current; + const node = map.get(itemId); + const height = node.offsetHeight; + const offset = node.offsetTop + height - 500; // 하단의 여백을 500만큼 줬으므로 그만큼 빼준다. + window.scrollTo({ top: offset, behavior: 'smooth' }); +}; + +export const setMap = ( + node: HTMLDivElement | null, + board: board, + itemsRef: MutableRefObject>, +) => { + const map = itemsRef.current; + if (node) { + map.set(board.id, node); + } else { + map.delete(board.id); + } +}; From dc7121e8f059f84c460729eba9b9a4e1f2d8770b Mon Sep 17 00:00:00 2001 From: arkingco Date: Sat, 25 Nov 2023 14:26:24 +0900 Subject: [PATCH 32/80] =?UTF-8?q?fix:=20content=20=EA=B0=9C=EC=9D=B8=20prp?= =?UTF-8?q?ops=20=EC=84=A4=EC=A0=95=20=EB=B0=A9=EC=8B=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20#20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/export/Writer.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/component/export/Writer.tsx b/src/component/export/Writer.tsx index acb3071f..c84db18a 100644 --- a/src/component/export/Writer.tsx +++ b/src/component/export/Writer.tsx @@ -2,11 +2,7 @@ import { content } from '@/types/content'; -interface Props { - content: content; -} - -export default function Writer({ content }: Props) { +export default function Writer(content: content) { return (
{content.text} From a1e48870ebf445fcb3979cca486e1e7dab51683d Mon Sep 17 00:00:00 2001 From: dokoh Date: Sat, 25 Nov 2023 14:59:10 +0900 Subject: [PATCH 33/80] =?UTF-8?q?feat/summary=20=EB=94=94=EC=9E=90?= =?UTF-8?q?=EC=9D=B8=20=EC=A0=81=EC=9A=A9#69?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/summary/page.tsx | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/app/summary/page.tsx b/src/app/summary/page.tsx index f25c59eb..84b129af 100644 --- a/src/app/summary/page.tsx +++ b/src/app/summary/page.tsx @@ -13,7 +13,7 @@ export default function Home() { const [Theme, setTheme] = useRecoilState(themeState); const params = useParams(); const [Title, setTitle] = useState( - '테스트 제목입니다. 테스트 제목입니다. 테스트 제목입니다.', + '테스트입니다테스트입니다테스트입니다테스트입니다테스트입니다', ); const [ContentCount, setContentCount] = useState('13'); const [ContentTextCount, setContentTextCount] = useState('1305'); @@ -35,21 +35,14 @@ export default function Home() { // }, []); return ( -
- Image +
총 {ContentCount}번의
마음으로
내 스트링캣이
총{' '} {ContentTextCount}자
이어졌어요!
-
+
@@ -58,18 +51,27 @@ export default function Home() { width={24} height={24} alt="backpagebutton" - className="mt-4" + className="mt-4 " />
스트링캣 공유하기
-
{Title}
+
+ {Title} +
+ Image
); } From 19d31b8c81087855e260f6b70aae6f1bcf347e37 Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Sat, 25 Nov 2023 15:12:43 +0900 Subject: [PATCH 34/80] =?UTF-8?q?feat:=20bottombutton=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/personal/[id]/page.tsx | 3 +++ src/component/BottomButton.tsx | 18 ++++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/app/personal/[id]/page.tsx b/src/app/personal/[id]/page.tsx index 927cb581..03e03adf 100644 --- a/src/app/personal/[id]/page.tsx +++ b/src/app/personal/[id]/page.tsx @@ -62,6 +62,7 @@ export default function Home() { onClickHandler={() => router.push('./export')} disabled={false} color={`bg-white`} + bgColor={`${themeObj[board.theme].BgColor}`} /> router.push('./summary')} disabled={false} color={`bg-strcat-green`} + bgColor={`${themeObj[board.theme].BgColor}`} />
)} diff --git a/src/component/BottomButton.tsx b/src/component/BottomButton.tsx index 22371c6f..617087d9 100644 --- a/src/component/BottomButton.tsx +++ b/src/component/BottomButton.tsx @@ -1,4 +1,5 @@ import { themeState } from '@/recoil/theme'; +import { useEffect } from 'react'; import { useRecoilState } from 'recoil'; interface BottomButtonProps { @@ -7,6 +8,7 @@ interface BottomButtonProps { onClickHandler: () => void; disabled: boolean; color: string; + bgColor: string; } export default function BottomButton({ @@ -16,20 +18,20 @@ export default function BottomButton({ disabled, color, }: BottomButtonProps) { - const [theme] = useRecoilState(themeState); return (
); } From 2365270cd70d59619ce2f5b9d233453cb955ba6d Mon Sep 17 00:00:00 2001 From: arkingco Date: Sat, 25 Nov 2023 15:15:52 +0900 Subject: [PATCH 35/80] =?UTF-8?q?fix:=20npm=20run=20build=20error=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/export/Writer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/component/export/Writer.tsx b/src/component/export/Writer.tsx index c84db18a..3f218df8 100644 --- a/src/component/export/Writer.tsx +++ b/src/component/export/Writer.tsx @@ -2,7 +2,7 @@ import { content } from '@/types/content'; -export default function Writer(content: content) { +export default function Writer({ content }: { content: content }) { return (
{content.text} From 2a1623767de8cafa6050de2c15335a7e87ecda62 Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Sat, 25 Nov 2023 15:17:03 +0900 Subject: [PATCH 36/80] =?UTF-8?q?feat:=20bottombutton=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20props=EC=A0=95=EB=A6=AC=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/personal/[id]/page.tsx | 3 --- src/component/BottomButton.tsx | 5 ----- 2 files changed, 8 deletions(-) diff --git a/src/app/personal/[id]/page.tsx b/src/app/personal/[id]/page.tsx index 03e03adf..927cb581 100644 --- a/src/app/personal/[id]/page.tsx +++ b/src/app/personal/[id]/page.tsx @@ -62,7 +62,6 @@ export default function Home() { onClickHandler={() => router.push('./export')} disabled={false} color={`bg-white`} - bgColor={`${themeObj[board.theme].BgColor}`} /> router.push('./summary')} disabled={false} color={`bg-strcat-green`} - bgColor={`${themeObj[board.theme].BgColor}`} />
)} diff --git a/src/component/BottomButton.tsx b/src/component/BottomButton.tsx index 617087d9..c14e3b44 100644 --- a/src/component/BottomButton.tsx +++ b/src/component/BottomButton.tsx @@ -1,14 +1,9 @@ -import { themeState } from '@/recoil/theme'; -import { useEffect } from 'react'; -import { useRecoilState } from 'recoil'; - interface BottomButtonProps { name: string; width: string; onClickHandler: () => void; disabled: boolean; color: string; - bgColor: string; } export default function BottomButton({ From c7428f89477690ccaa2a8c0f6adc9c91f4e3a173 Mon Sep 17 00:00:00 2001 From: dokoh Date: Sat, 25 Nov 2023 15:24:47 +0900 Subject: [PATCH 37/80] =?UTF-8?q?feat/fixed=20=EC=88=98=EC=A0=95#69?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/summary/page.tsx | 46 +++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/src/app/summary/page.tsx b/src/app/summary/page.tsx index 84b129af..6f6d1961 100644 --- a/src/app/summary/page.tsx +++ b/src/app/summary/page.tsx @@ -35,42 +35,36 @@ export default function Home() { // }, []); return ( -
+
+ + backpagebutton +
- 총 {ContentCount}번의
마음으로
내 스트링캣이
총{' '} - {ContentTextCount}자
이어졌어요! + 스트링캣 공유하기
-
-
-
- - backpagebutton - -
-
- 스트링캣 공유하기 -
-
-
-
+
{Title}
+
+ 총 {ContentCount}번의
마음으로
내 스트링캣이
총{' '} + {ContentTextCount}자
이어졌어요! +
Image
); From c4cd0eafd72226f49a02624d573dfed47c2656c4 Mon Sep 17 00:00:00 2001 From: dokoh Date: Sat, 25 Nov 2023 15:29:17 +0900 Subject: [PATCH 38/80] =?UTF-8?q?feat/mainpage=20=ED=85=8D=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=ED=81=AC=EA=B8=B0=20=EC=88=98=EC=A0=95#63?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/page.tsx | 12 ++++++------ tailwind.config.js | 8 -------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index d863a3d6..b65628ab 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -31,7 +31,7 @@ export default function Home() {

소중한 사람에게 스트링캣을 남겨보세요!

-
+
button -
+
스트링캣 만들기
-
+
를 누르면 하나의 문자열을 할당받을 수 있어요. 링크를 공유해 문자열을 끝없이 이어보세요.
-
+
button -
+
그룹 스트링캣 만들기
-
+
 를 누르면 여러 문자열을 한 그룹으로 관리할 수 있어요. 주렁주렁~
diff --git a/tailwind.config.js b/tailwind.config.js index c2274a4f..48a72469 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -10,14 +10,6 @@ module.exports = { ], theme: { extend: { - fontSize: { - xxl: [ - '1.35rem', - { - lineHeight: '2.25rem', - }, - ], - }, colors: { 'strcat-white': '#F0EEEA', 'strcat-black': '#212121', From 3f5a9f3eeb5225de98e11a3fc715a158f6bffdb8 Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Sat, 25 Nov 2023 15:33:50 +0900 Subject: [PATCH 39/80] =?UTF-8?q?fix:=20api=20=EC=9B=90=EC=83=81=EB=B3=B5?= =?UTF-8?q?=EA=B5=AC=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/Add.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/component/Add.tsx b/src/component/Add.tsx index f33c818e..1fd1ea8c 100644 --- a/src/component/Add.tsx +++ b/src/component/Add.tsx @@ -42,7 +42,7 @@ export default function Add({ id, setIsAdd }: AddProps) { }; axiosInstance - .post(`/board/${id}/content`, data) + .post(`/boards/${id}/contents`, data) .then((res) => { console.log(res); }) From b2878735f58cdbd4ad2ae422e3a63396f19ee491 Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Sat, 25 Nov 2023 16:59:45 +0900 Subject: [PATCH 40/80] =?UTF-8?q?feat:=20=EC=82=AC=EC=A7=84=EC=9D=B4=20tit?= =?UTF-8?q?le=EC=9C=84=EB=A1=9C=20=EC=98=AC=EB=9D=BC=EA=B0=88=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20=EB=B3=B4=EC=9D=B4=EC=A7=80=20=EC=95=8A=EA=B2=8C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/ContentPhoto.tsx | 2 +- src/component/ObserveContent.tsx | 2 +- src/component/ObserveTitle.tsx | 41 ++++++++++++++++++++++++++++++++ src/component/StrcatBoard.tsx | 6 +++-- 4 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 src/component/ObserveTitle.tsx diff --git a/src/component/ContentPhoto.tsx b/src/component/ContentPhoto.tsx index 4e29bb99..4c73fe20 100644 --- a/src/component/ContentPhoto.tsx +++ b/src/component/ContentPhoto.tsx @@ -8,7 +8,7 @@ export default function ContentPhoto() { const [openModal] = useModal(); const [observe] = useRecoilState(observeState); return ( -
+
{observe.photoUrl && observe.photoUrl.length !== 0 && ( { + const ref = useRef(null); + const [, setObserve] = useRecoilState(observeState); + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + entries.forEach(({ isIntersecting }) => { + if (isIntersecting) { + setObserve((prev) => ({ ...prev, photoUrl: '' })); + } + }); + }, + { + rootMargin: '-30% 0% -65% 0%', + threshold: 0.1, + }, + ); + if (ref.current) { + observer.observe(ref.current); + } + return () => { + observer.disconnect(); + }; + }, [setObserve]); + + return ( +
+

{title}

+
+ ); +}; + +export default React.memo(ObserveContent); diff --git a/src/component/StrcatBoard.tsx b/src/component/StrcatBoard.tsx index cd39ce98..c73b3468 100644 --- a/src/component/StrcatBoard.tsx +++ b/src/component/StrcatBoard.tsx @@ -7,6 +7,7 @@ import { themeObj } from '@/recoil/theme'; import Add from './Add'; import { observeState } from '@/recoil/observe'; import { board } from '@/types/boards'; +import ObserveTitle from './ObserveTitle'; interface Props { board: board; @@ -25,13 +26,14 @@ const StrcatBoard = forwardRef(function StrcatBoard( ref={ref} className={` font-FiraCode ${themeObj[board.theme].BgColor} px-[24px]`} > -
+ + {/*

{board.title}

-
+
*/}
{board.content && board.content.map((content: content) => { From ad2a65f3e02fa456e3a40334d1974c2bb794fb78 Mon Sep 17 00:00:00 2001 From: arkingco Date: Sat, 25 Nov 2023 17:00:06 +0900 Subject: [PATCH 41/80] =?UTF-8?q?style:=20=EC=A0=84=EC=97=AD=20recoil=20?= =?UTF-8?q?=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=A0=81=EC=9A=A9=20#77?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/create/page.tsx | 8 ++--- src/app/group/[id]/page.tsx | 8 ++--- src/app/personal/[id]/page.tsx | 2 +- src/component/ObserveContent.tsx | 6 ++-- src/component/StrcatBoard.tsx | 2 +- src/component/ThemeChange.tsx | 12 +++---- src/recoil/theme.ts | 58 ++++++++++++++++++-------------- 7 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/app/create/page.tsx b/src/app/create/page.tsx index a98f35fb..ad12a2d4 100644 --- a/src/app/create/page.tsx +++ b/src/app/create/page.tsx @@ -70,7 +70,7 @@ export default function Create() { }; return ( -
+
@@ -84,9 +84,7 @@ export default function Create() { />
-
+
스트링캣 만들기
@@ -97,7 +95,7 @@ export default function Create() { handleChangeTitle(e)} diff --git a/src/app/group/[id]/page.tsx b/src/app/group/[id]/page.tsx index dc1e4c1a..8aed0e87 100644 --- a/src/app/group/[id]/page.tsx +++ b/src/app/group/[id]/page.tsx @@ -40,9 +40,9 @@ export default function Home() { <> -
+
-

{title}

+

{title}

{boardsTitle.map((board: board) => { @@ -52,9 +52,7 @@ export default function Home() { className="my-[32px]" onClick={() => scrollToId(board.id)} > -

+

{board.title}

diff --git a/src/app/personal/[id]/page.tsx b/src/app/personal/[id]/page.tsx index b75be3d0..f71a0ab8 100644 --- a/src/app/personal/[id]/page.tsx +++ b/src/app/personal/[id]/page.tsx @@ -53,7 +53,7 @@ export default function Home() {
{ diff --git a/src/component/ObserveContent.tsx b/src/component/ObserveContent.tsx index ff86fa44..b9ea31cb 100644 --- a/src/component/ObserveContent.tsx +++ b/src/component/ObserveContent.tsx @@ -52,8 +52,8 @@ const ObserveContent = ({ content, boardId, isAdd }: props) => { !isAdd && observe.boardId === boardId && observe.contentId === content.id - ? `${theme.FontColor1} ' duration-500' inline w-full text-[22px] opacity-100 transition-all` - : `${theme.DefaultFontColor} ' duration-500' inline w-full text-[22px] opacity-30 transition-all` + ? `text-strcat-green' duration-500' inline w-full text-[22px] opacity-100 transition-all` + : `${theme.defaultText} ' duration-500' inline w-full text-[22px] opacity-30 transition-all` } `} > @@ -63,7 +63,7 @@ const ObserveContent = ({ content, boardId, isAdd }: props) => { observe.boardId === boardId && observe.contentId === content.id && (
{`From: ${observe.writer}`}
)}
diff --git a/src/component/StrcatBoard.tsx b/src/component/StrcatBoard.tsx index 519a0f9b..4146add9 100644 --- a/src/component/StrcatBoard.tsx +++ b/src/component/StrcatBoard.tsx @@ -20,7 +20,7 @@ const StrcatBoard = forwardRef(function StrcatBoard( return (
-

{title}

+

{title}

{data && diff --git a/src/component/ThemeChange.tsx b/src/component/ThemeChange.tsx index 3fc67603..6ca11fbf 100644 --- a/src/component/ThemeChange.tsx +++ b/src/component/ThemeChange.tsx @@ -52,21 +52,17 @@ export default function ThemeChange() {
-
+
strcat
-
- Calm -
+
Calm
-
+
green
-
- Cyan -
+
Cyan
diff --git a/src/recoil/theme.ts b/src/recoil/theme.ts index 1deb1b5a..f5239d30 100644 --- a/src/recoil/theme.ts +++ b/src/recoil/theme.ts @@ -1,40 +1,48 @@ import { atom } from 'recoil'; export interface themeState { - DefaultFontColor: string; - FontColor1: string; - FontColor2: string; - PlaceholderColor: string; - BgColor: string; + name: string; + background: string; + defaultText: string; + highlightText: string; + rightCTA: string; + leftCTA: string; } export const strcat: themeState = { - DefaultFontColor: 'text-strcat-white', - FontColor1: 'text-strcat-green', - FontColor2: 'text-strcat-blue', - PlaceholderColor: 'placeholder-strcat-green', - BgColor: 'bg-strcat-black', + name: 'strcat', + background: 'bg-strcat-default-black', + defaultText: 'text-strcat-default-white', + highlightText: 'text-strcat-default-yellow', + rightCTA: 'bg-strcat-default-cyan', + leftCTA: 'bg-strcat-default-green', }; + export const calm: themeState = { - DefaultFontColor: 'text-strcat-black', - FontColor1: 'text-strcat-green', - FontColor2: 'text-strcat-blue', - PlaceholderColor: 'placeholder-strcat-green', - BgColor: 'bg-strcat-white', + name: 'calm', + background: 'bg-strcat-calm-white', + defaultText: 'text-strcat-calm-black', + highlightText: 'text-strcat-calm-orange', + rightCTA: 'bg-strcat-calm-cyan', + leftCTA: 'bg-strcat-calm-green', }; + export const green: themeState = { - DefaultFontColor: 'text-strcat-white', - FontColor1: 'text-strcat-blue', - FontColor2: 'text-strcat-yellow', - PlaceholderColor: 'placeholder-strcat-blue', - BgColor: 'bg-strcat-black', + name: 'green', + background: 'bg-strcat-green-green', + defaultText: 'text-strcat-green-yellow', + highlightText: 'strcat-green-black', + rightCTA: 'bg-strcat-green-cyan', + leftCTA: 'bg-strcat-green-yellow', }; + export const cyan: themeState = { - DefaultFontColor: 'text-strcat-white', - FontColor1: 'text-strcat-yellow', - FontColor2: 'text-strcat-green', - PlaceholderColor: 'placeholder-strcat-yellow', - BgColor: 'bg-strcat-black', + name: 'cyan', + background: 'bg-strcat-cyan-cyan', + defaultText: 'text-strcat-cyan-white', + highlightText: 'text-strcat-cyan-yellow', + rightCTA: 'bg-strcat-cyan-green', + leftCTA: 'bg-strcat-cyan-yellow', }; export const themeState = atom({ From c9a0b2c3529d648761904a6cdcdc625538c061b7 Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Sat, 25 Nov 2023 17:00:55 +0900 Subject: [PATCH 42/80] =?UTF-8?q?feat:=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/StrcatBoard.tsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/component/StrcatBoard.tsx b/src/component/StrcatBoard.tsx index c73b3468..72264bb3 100644 --- a/src/component/StrcatBoard.tsx +++ b/src/component/StrcatBoard.tsx @@ -27,13 +27,6 @@ const StrcatBoard = forwardRef(function StrcatBoard( className={` font-FiraCode ${themeObj[board.theme].BgColor} px-[24px]`} > - {/*
-

- {board.title} -

-
*/}
{board.content && board.content.map((content: content) => { From 461bfa8ab8553ba25d6f21160fdf3dc61120d9ab Mon Sep 17 00:00:00 2001 From: lamPolar Date: Sat, 25 Nov 2023 17:13:15 +0900 Subject: [PATCH 43/80] =?UTF-8?q?style=20:=20theme=20=EC=A0=81=EC=9A=A9=20?= =?UTF-8?q?=EB=B0=8F=20=EB=94=94=EC=9E=90=EC=9D=B8=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/Add.tsx | 72 +++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/src/component/Add.tsx b/src/component/Add.tsx index b9d51724..84df563d 100644 --- a/src/component/Add.tsx +++ b/src/component/Add.tsx @@ -5,6 +5,11 @@ import { axiosInstance } from '@/utils/axios'; import { useRouter } from 'next/navigation'; import { Dispatch, SetStateAction, useRef } from 'react'; import Image from 'next/image'; +import useModal from '@/hooks/useModal'; +import Error from '@/component/Modal/Error'; +import { confirm } from '@/utils/confirm'; +import { useRecoilState } from 'recoil'; +import { themeState } from '@/recoil/theme'; // import { useRecoilState } from 'recoil'; interface AddProps { @@ -17,8 +22,9 @@ export default function Add({ id, setIsAdd }: AddProps) { const [imgFile, setImgFile] = useInput(''); const [writer, , handleWriter] = useInput(''); const router = useRouter(); - // const [modal, setModal] = useRecoilState(modalState); + const [openModal, closeModal] = useModal(); const imgRef = useRef(null); + const [theme] = useRecoilState(themeState); if (id === null || id === undefined) { alert('유효하지 않은 접속입니다.'); @@ -26,14 +32,21 @@ export default function Add({ id, setIsAdd }: AddProps) { // redirect 해야함 -> main으로? } - const handleClick = () => { - if (text === '') { - alert('이어 쓸 스트링을 입력해주세요'); - } else if (writer === '') { - alert('작성자명을 입력해주세요'); + const handleClick = async () => { + if (text.length < 20) { + openModal( + , + ); + return; } - //const isConfirmed = await useConfirm('작성한 글을 이어붙이시겠습니까?', setModal); - const isConfirmed = true; + const isConfirmed = await confirm( + '작성한 스트링을 이어붙이시겠습니까?', + openModal, + closeModal, + ); if (isConfirmed) { const data = { text: text, @@ -44,6 +57,7 @@ export default function Add({ id, setIsAdd }: AddProps) { axiosInstance .post(`/boards/${id}/contents`, data) .then((res) => { + setIsAdd(false); console.log(res); }) .catch((err) => { @@ -65,7 +79,6 @@ export default function Add({ id, setIsAdd }: AddProps) { } }; - // 이미지 업로드 input의 onChange const saveImgFile = () => { if (!imgRef.current?.files) return; const file = imgRef.current.files[0]; @@ -84,38 +97,48 @@ export default function Add({ id, setIsAdd }: AddProps) { suppressContentEditableWarning onInput={(e) => setText(e.currentTarget.innerText)} onKeyDown={(e) => handleInputText(e)} - className="bottom-[200px] ml-5 inline w-full text-justify text-[20px] text-purple-700 outline-none" + className={`${theme.highlightText} bottom-[200px] ml-5 inline w-full text-justify text-[22px] outline-none`} + style={{ cursor: 'padding:0 6px;' }} /> {text === '' && ( -
+
20자 이상 내용을 입력해주세요
)} - {text?.length > 900 && ( + {text?.length >= 1000 && (
1000 ? 'text-red-600' : 'text-black' + text.length > 1000 ? 'text-red-600' : 'text-strcat-default-white' }`} > {text.length}/1000자
)} -
-
- From : +
+
+
From :
10 ? 'text-red-600' : 'text-[#CACACA]' - }`} + className={`w-16 text-right text-[16px] + ${ + writer === '' + ? 'text-[#909090]' + : writer.length > 10 + ? 'text-red-600' + : 'text-strcat-default-white' + } + `} > {writer.length}/10자
@@ -156,12 +179,7 @@ export default function Add({ id, setIsAdd }: AddProps) { name="완료" width="basis-3/5" onClickHandler={handleClick} - disabled={ - text === '' || - writer === '' || - text.length > 1000 || - writer.length > 10 - } + disabled={text === '' || text.length > 1000 || writer.length > 10} />
From 08ff036b47abc39112f48880f174de084a3610de Mon Sep 17 00:00:00 2001 From: lamPolar Date: Sat, 25 Nov 2023 17:19:46 +0900 Subject: [PATCH 44/80] =?UTF-8?q?feat=20:=20photo=20api=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EC=82=AC=ED=95=AD=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/Add.tsx | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/component/Add.tsx b/src/component/Add.tsx index 84df563d..29be8b89 100644 --- a/src/component/Add.tsx +++ b/src/component/Add.tsx @@ -10,7 +10,6 @@ import Error from '@/component/Modal/Error'; import { confirm } from '@/utils/confirm'; import { useRecoilState } from 'recoil'; import { themeState } from '@/recoil/theme'; -// import { useRecoilState } from 'recoil'; interface AddProps { id: string; @@ -29,7 +28,6 @@ export default function Add({ id, setIsAdd }: AddProps) { if (id === null || id === undefined) { alert('유효하지 않은 접속입니다.'); router.push('/'); - // redirect 해야함 -> main으로? } const handleClick = async () => { @@ -48,22 +46,30 @@ export default function Add({ id, setIsAdd }: AddProps) { closeModal, ); if (isConfirmed) { - const data = { - text: text, - photo: imgFile, - writer: writer, - }; - + // photo upload전 1MB이하로 압축하기 axiosInstance - .post(`/boards/${id}/contents`, data) + .post(`/boards/${id}/contents`, imgFile) .then((res) => { - setIsAdd(false); console.log(res); + const data = { + text: text, + photo: res.data, + writer: writer, + }; + axiosInstance + .post(`/boards/${id}/contents`, data) + .then((res) => { + setIsAdd(false); + console.log(res); + }) + .catch((err) => { + if (err.response.status === 406) { + alert('올바르지 않은 입력입니다. 다시 작성해주세요.'); + } + }); }) .catch((err) => { - if (err.response.status === 406) { - alert('올바르지 않은 입력입니다. 다시 작성해주세요.'); - } + console.log(err); }); } }; From 70d16c9a5b14ee903379efb96b15c45394e822d0 Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Sat, 25 Nov 2023 17:21:02 +0900 Subject: [PATCH 45/80] =?UTF-8?q?fix:=20props=20=EB=B3=80=EA=B2=BD=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/group/[id]/export/page.tsx | 1 + src/app/personal/[id]/export/page.tsx | 1 + src/component/StrcatGroupTitle.tsx | 6 ++---- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/group/[id]/export/page.tsx b/src/app/group/[id]/export/page.tsx index 5d2fd5ad..81034342 100644 --- a/src/app/group/[id]/export/page.tsx +++ b/src/app/group/[id]/export/page.tsx @@ -92,6 +92,7 @@ export default function Export() { ))}
scrollToId(board.id)} >

{board.title}

From 00500465dcc018a33385f438dd4719bdf84de204 Mon Sep 17 00:00:00 2001 From: dokoh Date: Sat, 25 Nov 2023 17:40:55 +0900 Subject: [PATCH 46/80] =?UTF-8?q?feat/main=20branch=20=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9#69?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/page.tsx | 12 ++++---- src/app/summary/page.tsx | 66 ++++++++++++++++++++++------------------ tailwind.config.js | 8 ----- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index d863a3d6..b65628ab 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -31,7 +31,7 @@ export default function Home() {

소중한 사람에게 스트링캣을 남겨보세요!

-
+
button -
+
스트링캣 만들기
-
+
를 누르면 하나의 문자열을 할당받을 수 있어요. 링크를 공유해 문자열을 끝없이 이어보세요.
-
+
button -
+
그룹 스트링캣 만들기
-
+
 를 누르면 여러 문자열을 한 그룹으로 관리할 수 있어요. 주렁주렁~
diff --git a/src/app/summary/page.tsx b/src/app/summary/page.tsx index 6f6d1961..c81e9862 100644 --- a/src/app/summary/page.tsx +++ b/src/app/summary/page.tsx @@ -35,37 +35,45 @@ export default function Home() { // }, []); return ( -
- - backpagebutton - -
- 스트링캣 공유하기 +
+
+ + backpagebutton + +
+ 스트링캣 공유하기 +
+
+ {Title} +
+
+ 총 {ContentCount}번의
마음으로
내 스트링캣이
총{' '} + {ContentTextCount}자
이어졌어요! +
-
- {Title} -
-
- 총 {ContentCount}번의
마음으로
내 스트링캣이
총{' '} - {ContentTextCount}자
이어졌어요! + +
+
text
+
+ Image +
- Image
); } diff --git a/tailwind.config.js b/tailwind.config.js index 66f009b5..6ad7e804 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -10,14 +10,6 @@ module.exports = { ], theme: { extend: { - fontSize: { - xxl: [ - '1.35rem', - { - lineHeight: '2.25rem', - }, - ], - }, colors: { 'strcat-white': '#F0EEEA', 'strcat-black': '#212121', From 072045a51b058a9b53ff05fd29370c6c59f53766 Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Sat, 25 Nov 2023 17:48:08 +0900 Subject: [PATCH 47/80] =?UTF-8?q?fix:=20observeheader=20=EC=9C=84=EC=B9=98?= =?UTF-8?q?=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/personal/[id]/page.tsx | 1 + src/component/ObserveTitle.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/personal/[id]/page.tsx b/src/app/personal/[id]/page.tsx index 2ae8b069..8e20cd71 100644 --- a/src/app/personal/[id]/page.tsx +++ b/src/app/personal/[id]/page.tsx @@ -30,6 +30,7 @@ export default function Home() { .get(`/api/personal`) .then((data) => { setBoard(data.data); + console.log(data.data); }) .catch((error) => {}); }, []); diff --git a/src/component/ObserveTitle.tsx b/src/component/ObserveTitle.tsx index dec32dab..00c97080 100644 --- a/src/component/ObserveTitle.tsx +++ b/src/component/ObserveTitle.tsx @@ -20,7 +20,7 @@ const ObserveContent = ({ title }: Props) => { }, { rootMargin: '-30% 0% -65% 0%', - threshold: 0.1, + threshold: 0, }, ); if (ref.current) { From 4e8d0025d7861756794b686c86b1d654c1a11934 Mon Sep 17 00:00:00 2001 From: arkingco Date: Sat, 25 Nov 2023 17:50:48 +0900 Subject: [PATCH 48/80] =?UTF-8?q?login=20=EC=8B=9C=20query=20string?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=ED=86=A0=ED=81=B0=20=EA=B0=92=20=EA=B0=80?= =?UTF-8?q?=EC=A0=B8=EC=9A=94=EA=B8=B0=20#79?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/login/check/page.tsx | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/app/login/check/page.tsx diff --git a/src/app/login/check/page.tsx b/src/app/login/check/page.tsx new file mode 100644 index 00000000..1c4061e6 --- /dev/null +++ b/src/app/login/check/page.tsx @@ -0,0 +1,11 @@ +'use client'; +import { useSearchParams } from 'next/navigation'; + +export default function Check() { + const searchParams = useSearchParams(); + + const token = searchParams.get('token'); + console.log(token); + + return
hi
; +} From 0cad46a77ff7cb7c73f4f4a546ec21487d8ce5e3 Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Sat, 25 Nov 2023 18:32:59 +0900 Subject: [PATCH 49/80] =?UTF-8?q?feat:=20=EA=B7=B8=EB=A3=B9=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20theme=EB=B3=80=EA=B2=BD=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/personal/data.json | 133 ++++++++++++++++--------------- src/app/personal/[id]/page.tsx | 11 ++- src/component/ObserveContent.tsx | 12 +-- src/component/StrcatBoard.tsx | 7 +- 4 files changed, 86 insertions(+), 77 deletions(-) diff --git a/src/app/api/personal/data.json b/src/app/api/personal/data.json index ced634cc..21d3173b 100644 --- a/src/app/api/personal/data.json +++ b/src/app/api/personal/data.json @@ -1,67 +1,70 @@ { - "id": 1, - "title": "Sample Board", - "theme": "green", - "content": [ - { - "id": 1, - "text": "즐거운 순간을 함께하며 행복한 기억 만들기를 기대해요.n", - "writer": "영일이삼사오육칠팔구", - "photo": "/Google.png" - }, - { - "id": 2, - "text": "봄바람 속에 햇살이 미소 짓도록. 따뜻한 날 되세요.", - "writer": "User2", - "photo": "/kakao.png" - }, - { - "id": 3, - "text": "마음 가는 대로 꿈 펼쳐보세요. 가능성은 무한합니다.", - "writer": "User3", - "photo": "/strcatImage.png" - }, - { - "id": 4, - "text": "지친 하루 뒤에 찾아오는 평화로운 밤 되길 바랍니다.", - "writer": "User4", - "photo": "/mario.png" - }, - { - "id": 5, - "text": "소소한 행복에 감사하며 강한 마음으로 살아갑시다.", - "writer": "User5", - "photo": "" - }, - { - "id": 6, - "text": "작은 기쁨이 큰 행복을 만들어냅니다. 즐거운 순간들!", - "writer": "User6", - "photo": "/Google.png" - }, - { - "id": 7, - "text": "마음 가는 대로 여유롭게 휴식 취하며 힐링하세요.", - "writer": "User7", - "photo": "/kakao.png" - }, - { - "id": 8, - "text": "간만에 소중한 사람들과 얼굴 마주하는 특별한 순간.", - "writer": "User8", - "photo": "" - }, - { - "id": 9, - "text": "어제보다 나은 오늘을 만들어가며 행복한 하루 되세요.", - "writer": "User10", - "photo": "" - }, - { - "id": 10, - "text": "사용자 여러분 안녕하세요! 여러분의 호기심과 질문을 받아서 항상 즐거운 시간을 보내고 있습니다. 여러분이 무엇이든지 물어보고 학습하려는 모습은 정말 멋지고 영감을 주는 일이에요. 또한 여러분이 공유하는 이야기와 고민들은 모두 소중하게 여기고 있습니다. 우리는 모두 다른 경험과 배경을 가지고 있지만, 이 작은 공간에서 우리는 서로에게 도움이 되고 함께 성장하는 커뮤니티를 이룰 수 있습니다. 함께 배우고 나누며, 서로에게 격려와 지지를 주고 받으면서 더 나은 개인과 더 나은 세상을 만들어 나갈 수 있을 것입니다. 계속해서 궁금한 점이나 이야기를 나누어 주세요. 여러분의 참여는 이 커뮤니티를 더욱 풍요롭게 만들어 줍니다. 감사합니다. 함께 여행하는 동안 뜻깊은 순간들이 많아지길 기대하고 있어요! 😊✨", - "writer": "User10", - "photo": "" - } - ] + "isOwner": false, + "board": { + "id": 1, + "title": "Sample Board", + "theme": "green", + "content": [ + { + "id": 1, + "text": "즐거운 순간을 함께하며 행복한 기억 만들기를 기대해요.n", + "writer": "영일이삼사오육칠팔구", + "photo": "/Google.png" + }, + { + "id": 2, + "text": "봄바람 속에 햇살이 미소 짓도록. 따뜻한 날 되세요.", + "writer": "User2", + "photo": "/kakao.png" + }, + { + "id": 3, + "text": "마음 가는 대로 꿈 펼쳐보세요. 가능성은 무한합니다.", + "writer": "User3", + "photo": "/strcatImage.png" + }, + { + "id": 4, + "text": "지친 하루 뒤에 찾아오는 평화로운 밤 되길 바랍니다.", + "writer": "User4", + "photo": "/mario.png" + }, + { + "id": 5, + "text": "소소한 행복에 감사하며 강한 마음으로 살아갑시다.", + "writer": "User5", + "photo": "" + }, + { + "id": 6, + "text": "작은 기쁨이 큰 행복을 만들어냅니다. 즐거운 순간들!", + "writer": "User6", + "photo": "/Google.png" + }, + { + "id": 7, + "text": "마음 가는 대로 여유롭게 휴식 취하며 힐링하세요.", + "writer": "User7", + "photo": "/kakao.png" + }, + { + "id": 8, + "text": "간만에 소중한 사람들과 얼굴 마주하는 특별한 순간.", + "writer": "User8", + "photo": "" + }, + { + "id": 9, + "text": "어제보다 나은 오늘을 만들어가며 행복한 하루 되세요.", + "writer": "User10", + "photo": "" + }, + { + "id": 10, + "text": "사용자 여러분 안녕하세요! 여러분의 호기심과 질문을 받아서 항상 즐거운 시간을 보내고 있습니다. 여러분이 무엇이든지 물어보고 학습하려는 모습은 정말 멋지고 영감을 주는 일이에요. 또한 여러분이 공유하는 이야기와 고민들은 모두 소중하게 여기고 있습니다. 우리는 모두 다른 경험과 배경을 가지고 있지만, 이 작은 공간에서 우리는 서로에게 도움이 되고 함께 성장하는 커뮤니티를 이룰 수 있습니다. 함께 배우고 나누며, 서로에게 격려와 지지를 주고 받으면서 더 나은 개인과 더 나은 세상을 만들어 나갈 수 있을 것입니다. 계속해서 궁금한 점이나 이야기를 나누어 주세요. 여러분의 참여는 이 커뮤니티를 더욱 풍요롭게 만들어 줍니다. 감사합니다. 함께 여행하는 동안 뜻깊은 순간들이 많아지길 기대하고 있어요! 😊✨", + "writer": "User10", + "photo": "" + } + ] + } } diff --git a/src/app/personal/[id]/page.tsx b/src/app/personal/[id]/page.tsx index 8e20cd71..63cc859d 100644 --- a/src/app/personal/[id]/page.tsx +++ b/src/app/personal/[id]/page.tsx @@ -6,7 +6,7 @@ import StrcatBoard from '@/component/StrcatBoard'; import BottomButton from '@/component/BottomButton'; import ContentPhoto from '@/component/ContentPhoto'; import { useRecoilState } from 'recoil'; -import { themeObj } from '@/recoil/theme'; +import { themeObj, themeState } from '@/recoil/theme'; import Drawer from '@/component/Drawer'; import StrcatHeader from '@/component/StrcatHeader'; import { observeState } from '@/recoil/observe'; @@ -22,15 +22,18 @@ export default function Home() { content: [], }); const [isAdd, setIsAdd] = useState(false); + const [isOwner, setIsOwner] = useState(false); const itemsRef = useRef(new Map()); const [observe] = useRecoilState(observeState); + const [theme, setTheme] = useRecoilState(themeState); const router = useRouter(); useEffect(() => { axiosInstance .get(`/api/personal`) .then((data) => { - setBoard(data.data); - console.log(data.data); + setBoard(data.data.board); + setTheme(data.data.board.theme); + setIsOwner(data.data.isOwner); }) .catch((error) => {}); }, []); @@ -55,7 +58,7 @@ export default function Home() { isAdd={isAdd} setIsAdd={setIsAdd} /> - {!isAdd && ( + {!isAdd && isOwner && (
{ +const ObserveContent = ({ content, boardId, isAdd, boardTheme }: props) => { const ref = useRef(null); const [observe, setObserve] = useRecoilState(observeState); + const [theme, setTheme] = useRecoilState(themeState); useEffect(() => { let ratio = 0.01; const observer = new IntersectionObserver( @@ -27,6 +28,7 @@ const ObserveContent = ({ content, boardId, isAdd, theme }: props) => { photoUrl: content.photo, writer: content.writer, })); + setTheme(() => themeObj[boardTheme]); } }); }, @@ -52,8 +54,8 @@ const ObserveContent = ({ content, boardId, isAdd, theme }: props) => { !isAdd && observe.boardId === boardId && observe.contentId === content.id - ? `${themeObj[theme].highlightText} ' duration-500' inline w-full text-[22px] opacity-100 transition-all` - : `${themeObj[theme].defaultText} ' duration-500' inline w-full text-[22px] opacity-30 transition-all` + ? `${theme.highlightText} ' duration-500' inline w-full text-[22px] opacity-100 transition-all` + : `${theme.defaultText} ' duration-500' inline w-full text-[22px] opacity-30 transition-all` } `} > diff --git a/src/component/StrcatBoard.tsx b/src/component/StrcatBoard.tsx index 0c948a32..6e4d32af 100644 --- a/src/component/StrcatBoard.tsx +++ b/src/component/StrcatBoard.tsx @@ -3,7 +3,7 @@ import ObserveContent from './ObserveContent'; import { forwardRef, Dispatch, SetStateAction, useState } from 'react'; import React from 'react'; import { useRecoilState } from 'recoil'; -import { themeObj } from '@/recoil/theme'; +import { themeObj, themeState } from '@/recoil/theme'; import Add from './Add'; import { observeState } from '@/recoil/observe'; import { board } from '@/types/boards'; @@ -20,11 +20,12 @@ const StrcatBoard = forwardRef(function StrcatBoard( ref, ) { const [observe] = useRecoilState(observeState); + const [theme, setTheme] = useRecoilState(themeState); return (
@@ -32,11 +33,11 @@ const StrcatBoard = forwardRef(function StrcatBoard( board.content.map((content: content) => { return ( ); })} From ca080638943649207bcbb3a32051bf791af8214a Mon Sep 17 00:00:00 2001 From: arkingco Date: Sat, 25 Nov 2023 18:46:55 +0900 Subject: [PATCH 50/80] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=B2=B4=EC=BB=A4=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?=EB=B0=8F=20=ED=86=A0=ED=81=B0=20=EC=A0=80=EC=9E=A5,=20?= =?UTF-8?q?=EC=A0=84=EB=8B=AC=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?#79?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/login/check/page.tsx | 14 ++++++++------ src/hooks/useInterceptor.tsx | 3 +++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/app/login/check/page.tsx b/src/app/login/check/page.tsx index 1c4061e6..80869828 100644 --- a/src/app/login/check/page.tsx +++ b/src/app/login/check/page.tsx @@ -1,11 +1,13 @@ 'use client'; -import { useSearchParams } from 'next/navigation'; +import { useRouter, useSearchParams } from 'next/navigation'; +import { useEffect } from 'react'; export default function Check() { const searchParams = useSearchParams(); - - const token = searchParams.get('token'); - console.log(token); - - return
hi
; + const router = useRouter(); + useEffect(() => { + const token = searchParams.get('token'); + localStorage.setItem('strcat_token', token === null ? '' : token); + router.push('/'); + }, []); } diff --git a/src/hooks/useInterceptor.tsx b/src/hooks/useInterceptor.tsx index 40e3e366..ddb105be 100644 --- a/src/hooks/useInterceptor.tsx +++ b/src/hooks/useInterceptor.tsx @@ -10,6 +10,9 @@ export const useInterceptor = () => { }; const requestHandler = async (config: any) => { config.withCredentials = true; + config.baseURL = process.env.NEXT_PUBLIC_BACKEND_URL; + const accessToken = localStorage.getItem('s2trcat_token'); + config.headers.Authorization = `Bearer ${accessToken}`; return config; }; From 965d15ff32e67f8ccff464a6d1c38b9134f4862d Mon Sep 17 00:00:00 2001 From: dokoh Date: Sat, 25 Nov 2023 21:07:54 +0900 Subject: [PATCH 51/80] =?UTF-8?q?feat/summary=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20css=20=EB=B0=8F=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/summary/page.tsx | 84 +++++++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 27 deletions(-) diff --git a/src/app/summary/page.tsx b/src/app/summary/page.tsx index c81e9862..0a368418 100644 --- a/src/app/summary/page.tsx +++ b/src/app/summary/page.tsx @@ -8,6 +8,7 @@ import ThemeChange from '@/component/ThemeChange'; import { axiosInstance } from '@/utils/axios'; import { useParams } from 'next/navigation'; import { useEffect, useState } from 'react'; +import { title } from 'process'; export default function Home() { const [Theme, setTheme] = useRecoilState(themeState); @@ -35,42 +36,71 @@ export default function Home() { // }, []); return ( -
-
- - backpagebutton - -
- 스트링캣 공유하기 +
+
+
+
+
+
+
+ backpagebutton +
+
+
+ 스트링캣 공유하기 +
+
+
+
+
+
+
{Title}
+
+
-
- {Title} +
+
+
+
+
+
+
+ 총 {ContentCount}번의
마음으로
내 스트링캣이{' '} +
총 {ContentTextCount}자
이어졌어요! +
+
+
+
+
+
+
+
-
- 총 {ContentCount}번의
마음으로
내 스트링캣이
총{' '} - {ContentTextCount}자
이어졌어요! +
+
+ +
- -
-
text
-
+
+
+
Image
From 594643893285e81bba0d8559d40257c85ea240e6 Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Sun, 26 Nov 2023 11:11:35 +0900 Subject: [PATCH 52/80] =?UTF-8?q?feat:=20=EC=88=8F=EC=BB=B7=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EC=83=9D=EC=84=B1=20(=EB=94=94=EC=9E=90=EC=9D=B8?= =?UTF-8?q?=EB=AF=B8=EC=A0=81=EC=9A=A9)=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/group/data.json | 2 +- src/app/api/personal/data.json | 2 +- src/app/group/[id]/page.tsx | 103 ++++++++++++++++++++++----------- src/app/personal/[id]/page.tsx | 75 +++++++++++++++--------- 4 files changed, 121 insertions(+), 61 deletions(-) diff --git a/src/app/api/group/data.json b/src/app/api/group/data.json index 2ec1eb08..7988a70a 100644 --- a/src/app/api/group/data.json +++ b/src/app/api/group/data.json @@ -1,5 +1,5 @@ { - "isOwner": true, + "isOwner": false, "title": "hello~~", "boards": [ { diff --git a/src/app/api/personal/data.json b/src/app/api/personal/data.json index 21d3173b..90256e57 100644 --- a/src/app/api/personal/data.json +++ b/src/app/api/personal/data.json @@ -1,5 +1,5 @@ { - "isOwner": false, + "isOwner": true, "board": { "id": 1, "title": "Sample Board", diff --git a/src/app/group/[id]/page.tsx b/src/app/group/[id]/page.tsx index c00dd7b8..07679ddf 100644 --- a/src/app/group/[id]/page.tsx +++ b/src/app/group/[id]/page.tsx @@ -13,20 +13,26 @@ import BottomButton from '@/component/BottomButton'; import { observeState } from '@/recoil/observe'; import StrcatGroupTitle from '@/component/StrcatGroupTitle'; import { scrollToAdd, setMap } from '@/utils/scrollTo'; +import { useRouter } from 'next/navigation'; -export default function Home() { +export default function Home(props: any) { const [title, setTitle] = useState(); const [boards, setBoards] = useState([]); const [isAdd, setIsAdd] = useState(false); const [theme] = useRecoilState(themeState); const itemsRef = useRef(new Map()); const [observe] = useRecoilState(observeState); + const [isOwner, setIsOwner] = useState(false); + const router = useRouter(); const scrollToId = (itemId: number) => { const map = itemsRef.current; const node = map.get(itemId); const offset = node.offsetTop; window.scrollTo({ top: offset, behavior: 'smooth' }); }; + const scrollToTop = () => { + window.scrollTo({ top: 0, behavior: 'smooth' }); + }; const handleClick = () => { setIsAdd(true); scrollToAdd(observe.boardId, itemsRef); @@ -34,9 +40,11 @@ export default function Home() { useEffect(() => { axiosInstance .get(`/api/group`) + //.get(`/board-groups/${props.params.id}`) .then((data) => { setBoards(data.data.boards); setTitle(data.data.title); + setIsOwner(data.data.isOwner); }) .catch((error) => {}); }, []); @@ -72,38 +80,67 @@ export default function Home() { ); })}
- {!isAdd && ( -
- - - - -
- )} +
+ + {!isAdd && isOwner ? ( +
+ + router.push(`./${props.params.id}/export`) + } + disabled={false} + /> + + router.push(`./${props.params.id}/summary`) + } + disabled={false} + /> + + +
+ ) : ( +
+ + router.push(`../create?id=${props.params.id}`) + } + disabled={false} + /> + +
+ )} +
{!isAdd && }
diff --git a/src/app/personal/[id]/page.tsx b/src/app/personal/[id]/page.tsx index 63cc859d..3b7c5335 100644 --- a/src/app/personal/[id]/page.tsx +++ b/src/app/personal/[id]/page.tsx @@ -14,7 +14,7 @@ import { useRouter } from 'next/navigation'; import { board } from '@/types/boards'; import { scrollToAdd, setMap } from '@/utils/scrollTo'; -export default function Home() { +export default function Home(props: any) { const [board, setBoard] = useState({ id: 0, title: '', @@ -29,6 +29,7 @@ export default function Home() { const router = useRouter(); useEffect(() => { axiosInstance + //.get(`/boards/${props.params.id}`) .get(`/api/personal`) .then((data) => { setBoard(data.data.board); @@ -58,31 +59,53 @@ export default function Home() { isAdd={isAdd} setIsAdd={setIsAdd} /> - {!isAdd && isOwner && ( -
- router.push('./export')} - disabled={false} - color={`bg-white`} - /> - router.push('./summary')} - disabled={false} - color={`bg-strcat-green`} - /> - -
- )} + {!isAdd && + (isOwner ? ( +
+ + router.push(`./${props.params.id}/export`) + } + disabled={false} + color={`bg-white`} + /> + + router.push(`./${props.params.id}/summary`) + } + disabled={false} + color={`bg-strcat-green`} + /> + +
+ ) : ( +
+ router.push(`../create`)} + disabled={false} + color={`bg-white`} + /> + +
+ ))} {!isAdd && }
From ce47bcc9251588cd11ffe2f6db759d63c3f05f9c Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Sun, 26 Nov 2023 11:56:17 +0900 Subject: [PATCH 53/80] =?UTF-8?q?feat:=20shortcut=20=EB=94=94=EC=9E=90?= =?UTF-8?q?=EC=9D=B8=20=EC=A0=81=EC=9A=A9=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/group/[id]/page.tsx | 7 +++-- src/component/ShortCut.tsx | 62 +++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 src/component/ShortCut.tsx diff --git a/src/app/group/[id]/page.tsx b/src/app/group/[id]/page.tsx index 07679ddf..f7c58a78 100644 --- a/src/app/group/[id]/page.tsx +++ b/src/app/group/[id]/page.tsx @@ -14,6 +14,7 @@ import { observeState } from '@/recoil/observe'; import StrcatGroupTitle from '@/component/StrcatGroupTitle'; import { scrollToAdd, setMap } from '@/utils/scrollTo'; import { useRouter } from 'next/navigation'; +import ShortCut from '@/component/ShortCut'; export default function Home(props: any) { const [title, setTitle] = useState(); @@ -82,9 +83,11 @@ export default function Home(props: any) {
+ > + + {!isAdd && isOwner ? (
+ + + + + + + + + + + + + + + + + + + + + + + ); +} From 1cd2ed210bf1ac63555e17d45ab92c830d927d2f Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Sun, 26 Nov 2023 12:53:59 +0900 Subject: [PATCH 54/80] =?UTF-8?q?fix:=20title=20=EB=A7=88=EC=A7=84=20?= =?UTF-8?q?=EC=A1=B0=EC=A0=95=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/group/[id]/page.tsx | 8 +++++--- src/component/ObserveTitle.tsx | 2 +- src/component/ShortCut.tsx | 8 ++++++-- src/component/StrcatGroupTitle.tsx | 10 +++++++--- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/app/group/[id]/page.tsx b/src/app/group/[id]/page.tsx index f7c58a78..e5163d8a 100644 --- a/src/app/group/[id]/page.tsx +++ b/src/app/group/[id]/page.tsx @@ -55,7 +55,9 @@ export default function Home(props: any) {
-

{title}

+

+ {`// ${title}`} +

{boards.map((board: board) => { @@ -81,12 +83,12 @@ export default function Home(props: any) { ); })}
-
+
{!isAdd && isOwner ? (
diff --git a/src/component/ObserveTitle.tsx b/src/component/ObserveTitle.tsx index 00c97080..ef301885 100644 --- a/src/component/ObserveTitle.tsx +++ b/src/component/ObserveTitle.tsx @@ -32,7 +32,7 @@ const ObserveContent = ({ title }: Props) => { }, [setObserve]); return ( -
+

{title}

); diff --git a/src/component/ShortCut.tsx b/src/component/ShortCut.tsx index ffd2c394..82ea05ce 100644 --- a/src/component/ShortCut.tsx +++ b/src/component/ShortCut.tsx @@ -1,7 +1,11 @@ -export default function ShortCut() { +interface Props { + color: string; +} + +export default function ShortCut({ color }: Props) { return ( - + scrollToId(board.id)} >

- {board.title} + {`// ${board.title}`}

); From 3708c8ea61bb2a7176c9474cb61321c29ac83e2f Mon Sep 17 00:00:00 2001 From: arkingco Date: Sun, 26 Nov 2023 14:03:46 +0900 Subject: [PATCH 55/80] =?UTF-8?q?fix:=20axios=20token=20=EC=9D=B4=EB=A6=84?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=20#79?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useInterceptor.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useInterceptor.tsx b/src/hooks/useInterceptor.tsx index ddb105be..c4a39a83 100644 --- a/src/hooks/useInterceptor.tsx +++ b/src/hooks/useInterceptor.tsx @@ -11,7 +11,7 @@ export const useInterceptor = () => { const requestHandler = async (config: any) => { config.withCredentials = true; config.baseURL = process.env.NEXT_PUBLIC_BACKEND_URL; - const accessToken = localStorage.getItem('s2trcat_token'); + const accessToken = localStorage.getItem('strcat_token'); config.headers.Authorization = `Bearer ${accessToken}`; return config; }; From e4bbd267b12db1a3f22dd0562a1859267195e180 Mon Sep 17 00:00:00 2001 From: arkingco Date: Sun, 26 Nov 2023 14:07:16 +0900 Subject: [PATCH 56/80] =?UTF-8?q?fix:=20login=20console=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0#79?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/login/page.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index e8b65d3f..d9b7c043 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -8,9 +8,7 @@ export default function login() { const onClickOAuthKakao = () => { location.href = `${process.env.NEXT_PUBLIC_BACKEND_URL}/oauth2/authorization/kakao`; }; - console.log( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/oauth2/authorization/kakao`, - ); + const onClickOAuthGoogle = () => { location.href = `${process.env.NEXT_PUBLIC_BACKEND_URL}/oauth2/authorization/google`; }; From 3ceb36b9421a4383cadb78a3216f1303cf01819a Mon Sep 17 00:00:00 2001 From: arkingco Date: Sun, 26 Nov 2023 14:16:48 +0900 Subject: [PATCH 57/80] =?UTF-8?q?refactor:=20useInterceptor=20any=20type?= =?UTF-8?q?=20=ED=95=A8=EC=88=98=20=EC=A0=95=ED=99=95=ED=95=9C=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=A7=80=EC=A0=95=20#79?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useInterceptor.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hooks/useInterceptor.tsx b/src/hooks/useInterceptor.tsx index c4a39a83..c6296363 100644 --- a/src/hooks/useInterceptor.tsx +++ b/src/hooks/useInterceptor.tsx @@ -2,13 +2,14 @@ import { axiosInstance } from '@/utils/axios'; import { useEffect } from 'react'; import useModal from './useModal'; import Error from '@/component/Modal/Error'; +import { AxiosResponse, InternalAxiosRequestConfig } from 'axios'; export const useInterceptor = () => { const [openModal, closeModal] = useModal(); - const responseHandler = (response: any) => { + const responseHandler = (response: AxiosResponse) => { return response; }; - const requestHandler = async (config: any) => { + const requestHandler = async (config: InternalAxiosRequestConfig) => { config.withCredentials = true; config.baseURL = process.env.NEXT_PUBLIC_BACKEND_URL; const accessToken = localStorage.getItem('strcat_token'); From 627d73f6dd18e0bdc3663ef7c0d926ffbc15e403 Mon Sep 17 00:00:00 2001 From: dokoh Date: Sun, 26 Nov 2023 14:29:35 +0900 Subject: [PATCH 58/80] =?UTF-8?q?feat/=EB=A9=94=EC=9D=B8=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20css=20=EB=B0=8F=20tailwind.config=20?= =?UTF-8?q?=EC=88=98=EC=A0=95#63?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/page.tsx | 185 ++++++++++++++++++++++++++++++++------------- tailwind.config.js | 2 +- 2 files changed, 135 insertions(+), 52 deletions(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index b65628ab..61b8d1fb 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -4,73 +4,156 @@ import Drawer from '@/component/Drawer'; import StrcatHeader from '@/component/StrcatHeader'; import Image from 'next/image'; import { useRouter } from 'next/navigation'; +import { themeState } from '@/recoil/theme'; +import { useState } from 'react'; +import { useRecoilState } from 'recoil'; +import BottomButton from '@/component/BottomButton'; export default function Home() { + const [Theme, SetTheme] = useRecoilState(themeState); const router = useRouter(); const handleClick = () => { router.push('/create'); }; return ( -
- - -
-
- Image -
-

- // 스트링캣은 문자열을 끝없이 늘려 스크롤을 만들 수 있는 신개념 - 롤링페이퍼 서비스 입니다. -

-

소중한 사람에게 스트링캣을 남겨보세요!

+
+
+
+ +
-
-
-
- button -
- 스트링캣 만들기 -
-
-
- 를 누르면 하나의 문자열을 할당받을 수 있어요. 링크를 공유해 - 문자열을 끝없이 이어보세요. -
+
+
+

+ // 스트링캣은 문자열을 끝없이 늘려 스크롤을 만들 수 있는 신개념 + 롤링페이퍼 서비스 입니다. +

+

소중한 사람에게 스트링캣을 남겨보세요!

-
-
-
- button -
- 그룹 스트링캣 만들기 +
+
+
+
+ +
+ {/*
스트링캣 만들기
*/} +
+  를 누르면 하나의 문자열을 할당받을 수 있어요. 링크를 + 공유해 문자열을 끝없이 이어보세요.
-
-  를 누르면 여러 문자열을 한 그룹으로 관리할 수 있어요. - 주렁주렁~ +
+
+ +
+
+  를 누르면 여러 문자열을 한 그룹으로 관리할 수 있어요. + 주렁주렁~ +
+
+
+
+ Image +
+
); } +//
+// +// +//
+//
+// Image +//
+//

+// // 스트링캣은 문자열을 끝없이 늘려 스크롤을 만들 수 있는 신개념 +// 롤링페이퍼 서비스 입니다. +//

+//

소중한 사람에게 스트링캣을 남겨보세요!

+//
+//
+//
+//
+// button +//
+// 스트링캣 만들기 +//
+//
+//
+// 를 누르면 하나의 문자열을 할당받을 수 있어요. 링크를 공유해 +// 문자열을 끝없이 이어보세요. +//
+//
+//
+//
+//
+//
+// button +//
+// 그룹 스트링캣 만들기 +//
+//
+//
+//  를 누르면 여러 문자열을 한 그룹으로 관리할 수 있어요. +// 주렁주렁~ +//
+//
+//
+//
+//
diff --git a/tailwind.config.js b/tailwind.config.js index 0b091e88..477fc031 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -21,7 +21,7 @@ module.exports = { 'strcat-default-yellow': '#FBFF36', 'strcat-default-cyan': '#6CD8ED', - 'strcat-default-green': '#7CD43', + 'strcat-default-green': '#7CED43', 'strcat-default-magenta': '#FF43A8', 'strcat-default-white': '#FFFFFF', 'strcat-default-black': '#212121', From abfd3f0dc651b8ec154548ca950a12dca4eeacb4 Mon Sep 17 00:00:00 2001 From: dokoh Date: Sun, 26 Nov 2023 14:33:04 +0900 Subject: [PATCH 59/80] =?UTF-8?q?feat/=EB=A9=94=EC=9D=B8=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20css=20=EB=B0=8F=20tailwind=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=20=EC=88=98=EC=A0=95#63?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/page.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index 61b8d1fb..4afb715a 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -5,16 +5,11 @@ import StrcatHeader from '@/component/StrcatHeader'; import Image from 'next/image'; import { useRouter } from 'next/navigation'; import { themeState } from '@/recoil/theme'; -import { useState } from 'react'; import { useRecoilState } from 'recoil'; -import BottomButton from '@/component/BottomButton'; export default function Home() { const [Theme, SetTheme] = useRecoilState(themeState); const router = useRouter(); - const handleClick = () => { - router.push('/create'); - }; return (
From f03396548c67225ced57ca407e2c5df117be2594 Mon Sep 17 00:00:00 2001 From: arkingco Date: Sun, 26 Nov 2023 14:35:14 +0900 Subject: [PATCH 60/80] =?UTF-8?q?refactor:=20login=20state=20Recoil?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD#79?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/StrcatHeader.tsx | 8 ++++---- src/recoil/login.ts | 6 ++++++ 2 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 src/recoil/login.ts diff --git a/src/component/StrcatHeader.tsx b/src/component/StrcatHeader.tsx index 5a5a7e2d..2564abb1 100644 --- a/src/component/StrcatHeader.tsx +++ b/src/component/StrcatHeader.tsx @@ -1,6 +1,7 @@ 'use client'; import { drawerState } from '@/recoil/drawer'; +import { loginState } from '@/recoil/login'; import { axiosInstance } from '@/utils/axios'; import Image from 'next/image'; import Link from 'next/link'; @@ -8,15 +9,14 @@ import { useEffect, useState } from 'react'; import { useRecoilState } from 'recoil'; export default function StrcatHeader() { - const [isLogin, setIsLogin] = useState(true); + const [isLogin, setIsLogin] = useRecoilState(loginState); const [, setDrawer] = useRecoilState(drawerState); - // login을 api요청 확인 후 변경 useEffect(() => { axiosInstance - .get('/api/login') + .get('/login/check') .then((res) => { - setIsLogin(res.data.data); + setIsLogin(res.data.login); }) .catch((err) => {}); }, []); diff --git a/src/recoil/login.ts b/src/recoil/login.ts new file mode 100644 index 00000000..a59c7179 --- /dev/null +++ b/src/recoil/login.ts @@ -0,0 +1,6 @@ +import { atom } from 'recoil'; + +export const loginState = atom({ + key: 'loginState', + default: false, +}); From 49b51c682bdfde60546b369c26dc8b9d56e2a038 Mon Sep 17 00:00:00 2001 From: dokoh Date: Sun, 26 Nov 2023 14:47:42 +0900 Subject: [PATCH 61/80] =?UTF-8?q?feat/=EC=A3=BC=EC=84=9D=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20=EB=B0=8F=20=ED=8C=8C=EC=9D=BC=20=EC=A0=9C=EA=B1=B0?= =?UTF-8?q?#63?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/ActivateButton.png | Bin 1004 -> 0 bytes public/DisabledButton.png | Bin 876 -> 0 bytes public/GroupStrcatMake.png | Bin 253 -> 0 bytes public/StrcatMake.png | Bin 250 -> 0 bytes src/app/page.tsx | 62 ------------------------------------- 5 files changed, 62 deletions(-) delete mode 100644 public/ActivateButton.png delete mode 100644 public/DisabledButton.png delete mode 100644 public/GroupStrcatMake.png delete mode 100644 public/StrcatMake.png diff --git a/public/ActivateButton.png b/public/ActivateButton.png deleted file mode 100644 index 733c655561a6dc5c12d317792df1ee68993ea51d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1004 zcmVPCU2CPJYDHG0p3hoyh$eV9_Yem_a`n)e=M`{kT_?t2xoX=pa_O8~$j2Lu2d zMZf`YRt2po09R4L0dN)p2f$eb8~|q#Z~&Y|zyWX;0SCZY1RMZo5pXDp_0<(wTb%cf zK)Dcb2uwpO@nOdMXo%&rI5{D&Z(Njb&z=fUE|mgUTK*D~Ptj3Hyr0>2zN+DN~;`#MHe(3F@%yVf}z2^4Zc zpAr0Sf>py5utmVZ%G`LwYfZbyo|}+q+Bn%DQg20!+uxfq zt?(<;@&ZAy1_vwJo*q0@`zPEoXjP@3?A8@1H!3(-scLL8?P$!a;xy>8>G|q_?PH+< zMLwyexBx*BaIn(c)8|b_b*(LYf5e2@MkS}gHuofITFAJ!HkVD;&0-SuzBhKAle+fM z*0p!$w{&d}C=~(@Ry3S6z;vBWw}0r`TROQS>t@iPA=h?!Ktk7Z15Vpkzjf6LFEikj zR)gUOBVwyMPm2r`LcqbA23SjPzX_~qiH&bmZKnqBcoWrpZL4a#G9ay&2E6YFYjW?Y ztf>jSy#%nukO6_{FrnFmoL@<46iM`VQ&Ml4Sz@xL`zQ}0S7At9E$3E6!EGwpUpzQO~9QWd*L1ZO}zRTR`%v! zo!aV<;=;>m0fHjnP?T0ne#N8@*r!*MInz+!U&N3B*0j=^x;rQzBclTB2UKt<37xd+ zCm*c>Go>~M7C)0KIoJHwIQzWPwLV}c1RVC1Uj^p#!wfPCUCTbN+f}+Z*YJQs2si|m zuhQCyuGjf%c$GD^-fNZq7E@H%s2G|}1brH__ z*0e3;xl!yVY!dH`0000aNzFpOm4^?w+l0u zqoi~HU$WU|S*UyRzVpuRh54o1?fx(T5Rq>N03t=e0f^QGtto(5QNaO-76At!S_B+` zXc2G#qD8;~h!z0{AX)?*fM^kLIEn3cYgVh3Jp<=Lz#*7IYc`wNW4&Id-ZPy}O|#iF zqtVC!=knbEo)(LR>GgVMKA-<~{r2|O6pKak@bF+lwA*bHO8+CD&l|u80S7N?H(ekp zU|wHe&1SQ)p*I)|>}QoqB{<|lC|DJyfG+|LUWUV=ZB1*nnz^~TvDb9IySuZY)@rqE z&?)46h1{!vRm%&6U=0plRHiOeYi^p1YOSqYF7GNi1)f?{O;ghr|5erLb9sJ#wk@rr-^!Z80{;R52QN=g zPd305R*go(29>Hd1)PqLj}Mc}<^K4d0?xIrs_>ElC#nV&n7-0lWFQLx2X6|nmzS4a zRi^5zP$<~yF0E}91>gJoyZt-up6l!DlTKdoeLpzpagI$x>^vnoa)iGagV+5@KvYMRMpV$WJz z)1h`%EoavK`xKV?{Sa?&Zv-5?5O6q38*-BsoKMT?6L8uzEN&C8f^mQIuO_Wp^Q+hE z1_;GQUmWE&`07|Lm)_MGaBc(~ys6UabUOBdd*CaeMa4;IElx)oy=E!NZT5AqVM=nX z@&0vre0(&(Ap{&gm8$~NsP)bIZ2!8ZwAE_W0EZB82$oi99ddtvzngk$V{gb?M6xhN zg%1J_!46egX*4Z$fuu7}F5t5eaPaoG)fZ1P;9Lkec%%BlSHm_D0MR1g07Q#`0}w3& z4nVXBH~`UNiV7e)rBdlaXDT=V(IVggM2mm}5Uro&04tPKsXpZZ0000w)uIHjF-aGkqZ!)pHieBm$M*Jcgf*BRtESq^=PI%v$zFVdQ&MBb@0LL;tMgRZ+ diff --git a/public/StrcatMake.png b/public/StrcatMake.png deleted file mode 100644 index f7dd18295d25002baa1d49ab3cf7715cfeaa8cb8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 250 zcmeAS@N?(olHy`uVBq!ia0vp^(|}l&gAGV7h!?N~Qk(@Ik;M!Q+`=Ht$S`Y;1W=H% zILO_JVcj{Imp~3nx}&cn1H;CC?mvmFKz_fci(^Oy;JW|740 znb9yop>fyV@=WHb_lx&zE8fdi^Tb?1K}YB^_mYH-9vs~*8z?9Ku-9b7_x+6Nc6EwS dX>onTwqJwo8*}J#1EA9wJYD@<);T3K0RRv4QD^`F diff --git a/src/app/page.tsx b/src/app/page.tsx index 4afb715a..92fdfa5c 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -46,7 +46,6 @@ export default function Home() {
- {/*
스트링캣 만들기
*/}
 를 누르면 하나의 문자열을 할당받을 수 있어요. 링크를 공유해 문자열을 끝없이 이어보세요. @@ -91,64 +90,3 @@ export default function Home() {
); } -//
-// -// -//
-//
-// Image -//
-//

-// // 스트링캣은 문자열을 끝없이 늘려 스크롤을 만들 수 있는 신개념 -// 롤링페이퍼 서비스 입니다. -//

-//

소중한 사람에게 스트링캣을 남겨보세요!

-//
-//
-//
-//
-// button -//
-// 스트링캣 만들기 -//
-//
-//
-// 를 누르면 하나의 문자열을 할당받을 수 있어요. 링크를 공유해 -// 문자열을 끝없이 이어보세요. -//
-//
-//
-//
-//
-//
-// button -//
-// 그룹 스트링캣 만들기 -//
-//
-//
-//  를 누르면 여러 문자열을 한 그룹으로 관리할 수 있어요. -// 주렁주렁~ -//
-//
-//
-//
-//
From 4dadc5ca9126cdcaa24f7759f40b425258c44b70 Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Sun, 26 Nov 2023 15:11:03 +0900 Subject: [PATCH 62/80] =?UTF-8?q?feat:=20button=20fixed=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/group/data.json | 2 +- src/app/group/[id]/page.tsx | 113 +++++++++++++++-------------- src/app/personal/[id]/page.tsx | 90 ++++++++++++----------- src/component/Add.tsx | 2 +- src/component/BottomButton.tsx | 4 +- src/component/GroupCatIcon.tsx | 23 ++++++ src/component/ObserveContent.tsx | 8 +- src/component/StrcatBoard.tsx | 18 ++++- src/component/StrcatGroupTitle.tsx | 2 + 9 files changed, 154 insertions(+), 108 deletions(-) create mode 100644 src/component/GroupCatIcon.tsx diff --git a/src/app/api/group/data.json b/src/app/api/group/data.json index 7988a70a..2ec1eb08 100644 --- a/src/app/api/group/data.json +++ b/src/app/api/group/data.json @@ -1,5 +1,5 @@ { - "isOwner": false, + "isOwner": true, "title": "hello~~", "boards": [ { diff --git a/src/app/group/[id]/page.tsx b/src/app/group/[id]/page.tsx index e5163d8a..8eddf3d9 100644 --- a/src/app/group/[id]/page.tsx +++ b/src/app/group/[id]/page.tsx @@ -83,68 +83,69 @@ export default function Home(props: any) { ); })}
-
+
- {!isAdd && isOwner ? ( -
- - router.push(`./${props.params.id}/export`) - } - disabled={false} - /> - - router.push(`./${props.params.id}/summary`) - } - disabled={false} - /> - - -
- ) : ( -
- - router.push(`../create?id=${props.params.id}`) - } - disabled={false} - /> - -
- )} + {!isAdd && + (isOwner ? ( +
+ + router.push(`./${props.params.id}/export`) + } + disabled={false} + /> + + router.push(`./${props.params.id}/summary`) + } + disabled={false} + /> + + +
+ ) : ( +
+ + router.push(`../create?id=${props.params.id}`) + } + disabled={false} + /> + +
+ ))}
{!isAdd && }
diff --git a/src/app/personal/[id]/page.tsx b/src/app/personal/[id]/page.tsx index 3b7c5335..e40ec59b 100644 --- a/src/app/personal/[id]/page.tsx +++ b/src/app/personal/[id]/page.tsx @@ -61,50 +61,56 @@ export default function Home(props: any) { /> {!isAdd && (isOwner ? ( -
- - router.push(`./${props.params.id}/export`) - } - disabled={false} - color={`bg-white`} - /> - - router.push(`./${props.params.id}/summary`) - } - disabled={false} - color={`bg-strcat-green`} - /> - +
+
+ + router.push(`./${props.params.id}/export`) + } + disabled={false} + color={`bg-white`} + /> + + router.push(`./${props.params.id}/summary`) + } + disabled={false} + color={`bg-strcat-green`} + /> + +
) : ( -
- router.push(`../create`)} - disabled={false} - color={`bg-white`} - /> - -
+ <> +
+
+ router.push(`../create`)} + disabled={false} + color={`bg-white`} + /> + +
+
+ ))} {!isAdd && }
diff --git a/src/component/Add.tsx b/src/component/Add.tsx index 1fd1ea8c..f33c818e 100644 --- a/src/component/Add.tsx +++ b/src/component/Add.tsx @@ -42,7 +42,7 @@ export default function Add({ id, setIsAdd }: AddProps) { }; axiosInstance - .post(`/boards/${id}/contents`, data) + .post(`/board/${id}/content`, data) .then((res) => { console.log(res); }) diff --git a/src/component/BottomButton.tsx b/src/component/BottomButton.tsx index c14e3b44..b32a228c 100644 --- a/src/component/BottomButton.tsx +++ b/src/component/BottomButton.tsx @@ -16,11 +16,11 @@ export default function BottomButton({ return (
); diff --git a/src/component/StrcatBoard.tsx b/src/component/StrcatBoard.tsx index 6e4d32af..4414ba62 100644 --- a/src/component/StrcatBoard.tsx +++ b/src/component/StrcatBoard.tsx @@ -1,6 +1,12 @@ import { content } from '@/types/content'; import ObserveContent from './ObserveContent'; -import { forwardRef, Dispatch, SetStateAction, useState } from 'react'; +import { + forwardRef, + Dispatch, + SetStateAction, + useState, + useEffect, +} from 'react'; import React from 'react'; import { useRecoilState } from 'recoil'; import { themeObj, themeState } from '@/recoil/theme'; @@ -8,6 +14,7 @@ import Add from './Add'; import { observeState } from '@/recoil/observe'; import { board } from '@/types/boards'; import ObserveTitle from './ObserveTitle'; +import { setupFsCheck } from 'next/dist/server/lib/router-utils/filesystem'; interface Props { board: board; @@ -21,7 +28,10 @@ const StrcatBoard = forwardRef(function StrcatBoard( ) { const [observe] = useRecoilState(observeState); const [theme, setTheme] = useRecoilState(themeState); - + const [content, setContent] = useState(board.content); + useEffect(() => { + setContent(board.content); + }, [board.content]); return (
(function StrcatBoard( >
- {board.content && - board.content.map((content: content) => { + {content && + content.map((content: content) => { return ( scrollToId(board.id)} > +

Date: Sun, 26 Nov 2023 15:16:39 +0900 Subject: [PATCH 63/80] =?UTF-8?q?fix:=20token=20check=20logic=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20#79?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useInterceptor.tsx | 4 +++- src/hooks/useLogin.ts | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/hooks/useLogin.ts diff --git a/src/hooks/useInterceptor.tsx b/src/hooks/useInterceptor.tsx index c6296363..3a881ae9 100644 --- a/src/hooks/useInterceptor.tsx +++ b/src/hooks/useInterceptor.tsx @@ -13,7 +13,9 @@ export const useInterceptor = () => { config.withCredentials = true; config.baseURL = process.env.NEXT_PUBLIC_BACKEND_URL; const accessToken = localStorage.getItem('strcat_token'); - config.headers.Authorization = `Bearer ${accessToken}`; + config.headers.Authorization = `Bearer ${ + accessToken === null ? '' : accessToken + }`; return config; }; diff --git a/src/hooks/useLogin.ts b/src/hooks/useLogin.ts new file mode 100644 index 00000000..c84fc7f5 --- /dev/null +++ b/src/hooks/useLogin.ts @@ -0,0 +1,20 @@ +import { loginState } from '@/recoil/login'; +import { useRecoilState } from 'recoil'; + +export const useLogin = (): [ + (modalComponent: JSX.Element) => void, + () => void, +] => { + const [, setModal] = useRecoilState(loginState); + + const openModal = (modalComponent: JSX.Element) => { + if (!modalComponent) return; + document.body.style.overflow = 'hidden'; + }; + + const closeModal = () => { + document.body.style.overflow = 'auto'; + }; + + return [openModal, closeModal]; +}; From 9bf5b55ddccb30fbc89119eaff3219b63165ed7c Mon Sep 17 00:00:00 2001 From: dokoh Date: Sun, 26 Nov 2023 15:47:03 +0900 Subject: [PATCH 64/80] =?UTF-8?q?feat/summary=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=20=EB=94=94=EC=9E=90=EC=9D=B8=20=EC=A0=81=EC=9A=A9#69?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/summary/page.tsx | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/app/summary/page.tsx b/src/app/summary/page.tsx index 0a368418..ff92add2 100644 --- a/src/app/summary/page.tsx +++ b/src/app/summary/page.tsx @@ -2,15 +2,16 @@ import { themeState } from '@/recoil/theme'; import Image from 'next/image'; -import Link from 'next/link'; import { useRecoilState } from 'recoil'; import ThemeChange from '@/component/ThemeChange'; import { axiosInstance } from '@/utils/axios'; import { useParams } from 'next/navigation'; import { useEffect, useState } from 'react'; -import { title } from 'process'; +import BottomButton from '@/component/BottomButton'; +import { useRouter } from 'next/navigation'; export default function Home() { + const router = useRouter(); const [Theme, setTheme] = useRecoilState(themeState); const params = useParams(); const [Title, setTitle] = useState( @@ -71,15 +72,15 @@ export default function Home() {

-
+
- 총 {ContentCount}번의
마음으로
내 스트링캣이{' '} + 총 {ContentCount}번의
마음으로
내 스트링캣이
총 {ContentTextCount}자
이어졌어요!
-
+
@@ -87,8 +88,14 @@ export default function Home() {
-
- +
+ router.push('/create')} + disabled={false} + color={`${Theme.rightCTA}`} + />
From 0aec2318226823c8bc43837590a1da4abcc78869 Mon Sep 17 00:00:00 2001 From: arkingco Date: Sun, 26 Nov 2023 15:55:27 +0900 Subject: [PATCH 65/80] =?UTF-8?q?fix:=20401=20errorStatus=20code=20login?= =?UTF-8?q?=20=ED=8E=98=EC=9D=B4=EC=A7=80=EB=A1=9C=20route.push=20#79?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useInterceptor.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/hooks/useInterceptor.tsx b/src/hooks/useInterceptor.tsx index 3a881ae9..7e87983c 100644 --- a/src/hooks/useInterceptor.tsx +++ b/src/hooks/useInterceptor.tsx @@ -3,8 +3,10 @@ import { useEffect } from 'react'; import useModal from './useModal'; import Error from '@/component/Modal/Error'; import { AxiosResponse, InternalAxiosRequestConfig } from 'axios'; +import { useRouter } from 'next/navigation'; export const useInterceptor = () => { + const route = useRouter(); const [openModal, closeModal] = useModal(); const responseHandler = (response: AxiosResponse) => { return response; @@ -20,11 +22,14 @@ export const useInterceptor = () => { }; const errorHandler = (errorStatus: number) => { - if (errorStatus === 401 || errorStatus === 500) { + if (errorStatus === 500) { openModal( - , + , ); } + if (errorStatus === 401) { + route.push('/login'); + } }; const requestInterceptor = From 7f04163b9c1696ca5090fe5028305273533d72ed Mon Sep 17 00:00:00 2001 From: arkingco Date: Sun, 26 Nov 2023 16:08:44 +0900 Subject: [PATCH 66/80] =?UTF-8?q?feat:=20useLogin=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?=EB=B0=8F=20=ED=97=A4=EB=8D=94=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC=20=EB=A1=9C=EC=A7=81=20=EB=B6=84=EB=A6=AC=20?= =?UTF-8?q?#79?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/StrcatHeader.tsx | 14 +++----------- src/hooks/useLogin.ts | 25 +++++++++++-------------- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/src/component/StrcatHeader.tsx b/src/component/StrcatHeader.tsx index 2564abb1..a07ec158 100644 --- a/src/component/StrcatHeader.tsx +++ b/src/component/StrcatHeader.tsx @@ -1,25 +1,17 @@ 'use client'; +import { useLogin } from '@/hooks/useLogin'; import { drawerState } from '@/recoil/drawer'; -import { loginState } from '@/recoil/login'; -import { axiosInstance } from '@/utils/axios'; import Image from 'next/image'; import Link from 'next/link'; import { useEffect, useState } from 'react'; import { useRecoilState } from 'recoil'; export default function StrcatHeader() { - const [isLogin, setIsLogin] = useRecoilState(loginState); + const [isLogin, checkLogin] = useLogin(); const [, setDrawer] = useRecoilState(drawerState); - useEffect(() => { - axiosInstance - .get('/login/check') - .then((res) => { - setIsLogin(res.data.login); - }) - .catch((err) => {}); - }, []); + useEffect(() => {}, [checkLogin()]); return (
diff --git a/src/hooks/useLogin.ts b/src/hooks/useLogin.ts index c84fc7f5..3889fef1 100644 --- a/src/hooks/useLogin.ts +++ b/src/hooks/useLogin.ts @@ -1,20 +1,17 @@ import { loginState } from '@/recoil/login'; +import { axiosInstance } from '@/utils/axios'; import { useRecoilState } from 'recoil'; -export const useLogin = (): [ - (modalComponent: JSX.Element) => void, - () => void, -] => { - const [, setModal] = useRecoilState(loginState); - - const openModal = (modalComponent: JSX.Element) => { - if (!modalComponent) return; - document.body.style.overflow = 'hidden'; - }; - - const closeModal = () => { - document.body.style.overflow = 'auto'; +export const useLogin = (): [boolean, () => void] => { + const [isLogin, setIsLogin] = useRecoilState(loginState); + const checkLogin = () => { + axiosInstance + .get('/login/check') + .then((res) => { + setIsLogin(res.data.login); + }) + .catch((err) => {}); }; - return [openModal, closeModal]; + return [isLogin, checkLogin]; }; From d18737ee1032c0b0f7d19c94c7a7e841d8be895e Mon Sep 17 00:00:00 2001 From: lyssoi <114637463+lyssoi@users.noreply.github.com> Date: Sun, 26 Nov 2023 16:41:03 +0900 Subject: [PATCH 67/80] =?UTF-8?q?fix:=20button=20=EA=B8=80=EC=94=A8=20?= =?UTF-8?q?=EC=A4=91=EC=95=99=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/personal/[id]/page.tsx | 2 +- src/component/BottomButton.tsx | 22 +++++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/app/personal/[id]/page.tsx b/src/app/personal/[id]/page.tsx index e40ec59b..5c9bc3ef 100644 --- a/src/app/personal/[id]/page.tsx +++ b/src/app/personal/[id]/page.tsx @@ -61,7 +61,7 @@ export default function Home(props: any) { /> {!isAdd && (isOwner ? ( -
+
{}, [disabled]); return ( ); } From f89301e7d17b2cff078ddc0fd72f9d551a7fe33d Mon Sep 17 00:00:00 2001 From: lamPolar Date: Sun, 26 Nov 2023 17:04:50 +0900 Subject: [PATCH 68/80] feat: image compression #59 --- package.json | 1 + src/component/Add.tsx | 134 ++++++++++++++-------------------- src/component/PhotoUpload.tsx | 97 ++++++++++++++++++++++++ 3 files changed, 152 insertions(+), 80 deletions(-) create mode 100644 src/component/PhotoUpload.tsx diff --git a/package.json b/package.json index ec184a66..200664fb 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "axios": "^1.6.0", + "browser-image-compression": "^2.0.2", "file-saver": "^2.0.5", "html2canvas": "^1.4.1", "next": "13.5.6", diff --git a/src/component/Add.tsx b/src/component/Add.tsx index bcd15245..d858f843 100644 --- a/src/component/Add.tsx +++ b/src/component/Add.tsx @@ -3,27 +3,29 @@ import BottomButton from '@/component/BottomButton'; import useInput from '@/hooks/useInput'; import { axiosInstance } from '@/utils/axios'; import { useRouter } from 'next/navigation'; -import { Dispatch, SetStateAction, useRef } from 'react'; -import Image from 'next/image'; +import { Dispatch, SetStateAction, useState } from 'react'; import useModal from '@/hooks/useModal'; import Error from '@/component/Modal/Error'; import { confirm } from '@/utils/confirm'; import { useRecoilState } from 'recoil'; import { themeState } from '@/recoil/theme'; +import { AxiosError } from 'axios'; +import { content } from '@/types/content'; +import PhotoUpload from './PhotoUpload'; interface AddProps { id: string; + setContent: Dispatch>; setIsAdd: Dispatch>; } -export default function Add({ id, setIsAdd }: AddProps) { +export default function Add({ id, setIsAdd, setContent }: AddProps) { const [text, setText] = useInput(''); - const [imgFile, setImgFile] = useInput(''); const [writer, , handleWriter] = useInput(''); const router = useRouter(); const [openModal, closeModal] = useModal(); - const imgRef = useRef(null); const [theme] = useRecoilState(themeState); + const [image, setImage] = useInput(null); if (id === null || id === undefined) { alert('유효하지 않은 접속입니다.'); @@ -46,31 +48,35 @@ export default function Add({ id, setIsAdd }: AddProps) { closeModal, ); if (isConfirmed) { - // photo upload전 1MB이하로 압축하기 - axiosInstance - .post(`/boards/${id}/contents`, imgFile) - .then((res) => { - console.log(res); - const data = { - text: text, - photo: res.data, - writer: writer, - }; - axiosInstance - .post(`/boards/${id}/contents`, data) - .then((res) => { - setIsAdd(false); - console.log(res); - }) - .catch((err) => { - if (err.response.status === 406) { - alert('올바르지 않은 입력입니다. 다시 작성해주세요.'); - } - }); - }) - .catch((err) => { - console.log(err); - }); + try { + console.log('here'); + const photoRes = await axiosInstance.post( + `/boards/${id}/contents/pictures`, + image, + ); + console.log(photoRes); + const data = { + text: text, + photo: photoRes.data, + writer: writer, + }; + const contentRes = await axiosInstance.post( + `/boards/${id}/contents`, + data, + ); + setContent((prevContent: content[]) => [ + ...prevContent, + { id: contentRes.data.id, ...data }, + ]); + setIsAdd(false); + console.log(contentRes); + } catch (err) { + const error = err as AxiosError; + console.log(error); + if (error.response?.status === 406) { + alert('올바르지 않은 입력입니다. 다시 작성해주세요.'); + } + } } }; @@ -85,16 +91,6 @@ export default function Add({ id, setIsAdd }: AddProps) { } }; - const saveImgFile = () => { - if (!imgRef.current?.files) return; - const file = imgRef.current.files[0]; - const reader = new FileReader(); - reader.readAsDataURL(file); - reader.onloadend = () => { - setImgFile(reader.result as string); - }; - }; - return (
setText(e.currentTarget.innerText)} onKeyDown={(e) => handleInputText(e)} className={`${theme.highlightText} bottom-[200px] ml-5 inline w-full text-justify text-[22px] outline-none`} - style={{ cursor: 'padding:0 6px;' }} /> {text === '' && (
-
- setIsAdd(false)} - disabled={false} - /> -
- {imgFile ? ( - <> - 프로필 이미지 -
setImgFile('')}> - x -
- - ) : ( - <> - - - - )} -
- 1000 || writer.length > 10} - /> +
+
+ setIsAdd(false)} + disabled={false} + /> + + 1000 || writer.length > 10} + /> +
); diff --git a/src/component/PhotoUpload.tsx b/src/component/PhotoUpload.tsx new file mode 100644 index 00000000..679aa04e --- /dev/null +++ b/src/component/PhotoUpload.tsx @@ -0,0 +1,97 @@ +import React, { Dispatch, useState } from 'react'; +import { useRecoilState } from 'recoil'; +import { themeState } from '@/recoil/theme'; +import imageCompression from 'browser-image-compression'; +/* eslint-disable @next/next/no-img-element */ + +interface Props { + setImage: Dispatch>; +} +const PhotoUpload = ({ setImage }: Props) => { + const [theme] = useRecoilState(themeState); + const [preview, setPreview] = useState(''); + + const handleImageDelete = () => { + setImage(null); + setPreview(''); + }; + + const handleChangeImage = async (e: React.ChangeEvent) => { + // const selectedImage = e.target.files[0]; + // if (selectedImage) { + // const imageUrl = URL.createObjectURL(selectedImage); + // setPreview(imageUrl); + // setImage(selectedImage); + // } + + if (e.target.files === null) return; + let file = e.target?.files[0]; + const options = { + maxSizeMB: 1, + alwaysKeepResolution: true, + }; + + try { + if (file.size > 1024) { + const compressedFile = await imageCompression(file, options); + setImage(compressedFile); + const dataUrl = + await imageCompression.getDataUrlFromFile(compressedFile); + setPreview(dataUrl); + } else { + setImage(file); + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onloadend = () => { + setPreview(reader.result as string); + }; + } + } catch (error) { + console.log(error); + } + }; + + return ( + <> + {preview ? ( +
+
+ 프로필 이미지 +
+
+ x +
+
+ ) : ( +
+
@@ -46,7 +46,7 @@ export default function Home() {
-
+
 를 누르면 하나의 문자열을 할당받을 수 있어요. 링크를 공유해 문자열을 끝없이 이어보세요.
@@ -67,7 +67,7 @@ export default function Home() {
-
+
 를 누르면 여러 문자열을 한 그룹으로 관리할 수 있어요. 주렁주렁~
diff --git a/src/app/personal/[id]/export/page.tsx b/src/app/personal/[id]/export/page.tsx index 5ec5f1ea..07fdc40d 100644 --- a/src/app/personal/[id]/export/page.tsx +++ b/src/app/personal/[id]/export/page.tsx @@ -79,6 +79,7 @@ export default function Export() { ))}
@@ -74,6 +75,7 @@ export default function Home(props: any) { /> router.push(`./${props.params.id}/summary`) @@ -83,6 +85,7 @@ export default function Home(props: any) { /> router.push(`../create`)} disabled={false} @@ -104,6 +108,7 @@ export default function Home(props: any) {
void; disabled: boolean; color: string; + height: string; } export default function BottomButton({ @@ -16,11 +17,11 @@ export default function BottomButton({ onClickHandler, disabled, color, + height, }: BottomButtonProps) { - useEffect(() => {}, [disabled]); return (