From bbc1f6d9e9f3a849bba8b3e5069bd110493d67e5 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Mon, 20 May 2024 11:07:57 +0900 Subject: [PATCH 01/34] =?UTF-8?q?fix:=20=EC=9D=B8=ED=92=8B=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EB=8A=94=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20react-hook-form=EC=9C=BC=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Modal/AddFolderModal/AddFolderModal.tsx | 39 ++++++++++--------- components/Modal/EditModal/EditModal.tsx | 35 +++++++++++------ 2 files changed, 43 insertions(+), 31 deletions(-) diff --git a/components/Modal/AddFolderModal/AddFolderModal.tsx b/components/Modal/AddFolderModal/AddFolderModal.tsx index 5f754dc1c..aec80485c 100644 --- a/components/Modal/AddFolderModal/AddFolderModal.tsx +++ b/components/Modal/AddFolderModal/AddFolderModal.tsx @@ -1,39 +1,40 @@ import * as S from '../EditModal/EditModal.styled'; import BaseModal from '../BaseModal/BaseModal'; -import useValidate from '@/hooks/useValidate'; import Input from '@/components/Input/Input'; -import { ChangeEvent, useState } from 'react'; import { postFolder } from '@/pages/api/api'; import { useRouter } from 'next/router'; +import { Controller, useForm } from 'react-hook-form'; function AddFolderModal() { - const { checkText, textError } = useValidate(); - const [title, setTitle] = useState(''); const router = useRouter(); + const { handleSubmit, control } = useForm(); - const addFolder = async (e: ChangeEvent) => { - e.preventDefault(); - await postFolder(title); + const addFolder = async (data: any) => { + await postFolder(data.folder); router.reload(); }; return ( - + 폴더 추가 - { - checkText(e.target.value); - setTitle(e.target.value); + ( + + )} /> - - {textError && {textError}} - 추가하기 diff --git a/components/Modal/EditModal/EditModal.tsx b/components/Modal/EditModal/EditModal.tsx index af6926f34..0348f168c 100644 --- a/components/Modal/EditModal/EditModal.tsx +++ b/components/Modal/EditModal/EditModal.tsx @@ -1,26 +1,37 @@ import * as S from './EditModal.styled'; import BaseModal from '../BaseModal/BaseModal'; -import useValidate from '@/hooks/useValidate'; import { Button } from '@/components/Button/Button'; import Input from '@/components/Input/Input'; +import { Controller, useForm } from 'react-hook-form'; function EditModal() { - const { checkText, textError } = useValidate(); + const { handleSubmit, control } = useForm(); + + const editFolder = (data: any) => { + console.log(data); + }; return ( - + 폴더이름 변경 - checkText(e.target.value)} - size="sm" + ( + + )} /> - - {textError && {textError}} - From 856179128a7294a77d993955079c8ffe69ed2049 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Mon, 20 May 2024 13:28:27 +0900 Subject: [PATCH 02/34] =?UTF-8?q?fix:=20=EB=A9=94=EC=9D=B8=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=9D=B4=EB=AF=B8=EC=A7=80=ED=83=9C?= =?UTF-8?q?=EA=B7=B8=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 552 ++++++++++++++++++++++++++++++++++++++++- package.json | 1 + pages/index.tsx | 5 +- styles/index.styled.ts | 25 +- 4 files changed, 574 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 623d4f649..1c8b08f39 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "react": "^18", "react-dom": "^18", "react-hook-form": "^7.51.4", + "sharp": "^0.33.4", "styled-components": "^6.1.11" }, "devDependencies": { @@ -392,6 +393,15 @@ "node": ">=6.9.0" } }, + "node_modules/@emnapi/runtime": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.2.0.tgz", + "integrity": "sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@emotion/babel-plugin": { "version": "11.11.0", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", @@ -689,6 +699,437 @@ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.4.tgz", + "integrity": "sha512-p0suNqXufJs9t3RqLBO6vvrgr5OhgbWp76s5gTRvdmxmuv9E1rcaqGUsl3l4mKVmXPkTkTErXediAui4x+8PSA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.2" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.4.tgz", + "integrity": "sha512-0l7yRObwtTi82Z6ebVI2PnHT8EB2NxBgpK2MiKJZJ7cz32R4lxd001ecMhzzsZig3Yv9oclvqqdV93jo9hy+Dw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.2" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.2.tgz", + "integrity": "sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=11", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.2.tgz", + "integrity": "sha512-Ofw+7oaWa0HiiMiKWqqaZbaYV3/UGL2wAPeLuJTx+9cXpCRdvQhCLG0IH8YGwM0yGWGLpsF4Su9vM1o6aer+Fw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=10.13", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.2.tgz", + "integrity": "sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.2.tgz", + "integrity": "sha512-x7kCt3N00ofFmmkkdshwj3vGPCnmiDh7Gwnd4nUwZln2YjqPxV1NlTyZOvoDWdKQVDL911487HOueBvrpflagw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.2.tgz", + "integrity": "sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.2.tgz", + "integrity": "sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.2.tgz", + "integrity": "sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.2.tgz", + "integrity": "sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.4.tgz", + "integrity": "sha512-RUgBD1c0+gCYZGCCe6mMdTiOFS0Zc/XrN0fYd6hISIKcDUbAW5NtSQW9g/powkrXYm6Vzwd6y+fqmExDuCdHNQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.2" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.4.tgz", + "integrity": "sha512-2800clwVg1ZQtxwSoTlHvtm9ObgAax7V6MTAB/hDT945Tfyy3hVkmiHpeLPCKYqYR1Gcmv1uDZ3a4OFwkdBL7Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.2" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.4.tgz", + "integrity": "sha512-h3RAL3siQoyzSoH36tUeS0PDmb5wINKGYzcLB5C6DIiAn2F3udeFAum+gj8IbA/82+8RGCTn7XW8WTFnqag4tQ==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.31", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.2" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.4.tgz", + "integrity": "sha512-GoR++s0XW9DGVi8SUGQ/U4AeIzLdNjHka6jidVwapQ/JebGVQIpi52OdyxCNVRE++n1FCLzjDovJNozif7w/Aw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.2" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.4.tgz", + "integrity": "sha512-nhr1yC3BlVrKDTl6cO12gTpXMl4ITBUZieehFvMntlCXFzH2bvKG76tBL2Y/OqhupZt81pR7R+Q5YhJxW0rGgQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.2" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.4.tgz", + "integrity": "sha512-uCPTku0zwqDmZEOi4ILyGdmW76tH7dm8kKlOIV1XC5cLyJ71ENAAqarOHQh0RLfpIpbV5KOpXzdU6XkJtS0daw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.2" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.4.tgz", + "integrity": "sha512-Bmmauh4sXUsUqkleQahpdNXKvo+wa1V9KhT2pDA4VJGKwnKMJXiSTGphn0gnJrlooda0QxCtXc6RX1XAU6hMnQ==", + "cpu": [ + "wasm32" + ], + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.1.1" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.4.tgz", + "integrity": "sha512-99SJ91XzUhYHbx7uhK3+9Lf7+LjwMGQZMDlO/E/YVJ7Nc3lyDFZPGhjwiYdctoH2BOzW9+TnfqcaMKt0jHLdqw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.4.tgz", + "integrity": "sha512-3QLocdTRVIrFNye5YocZl+KKpYKP+fksi1QhmOArgx7GyhIbQp/WrJRu176jm8IxromS7RIkzMiMINVdBtC8Aw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -1614,6 +2055,18 @@ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1626,8 +2079,32 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/combined-stream": { "version": "1.0.8", @@ -1837,6 +2314,14 @@ "node": ">=6" } }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "engines": { + "node": ">=8" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -4426,6 +4911,56 @@ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" }, + "node_modules/sharp": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.4.tgz", + "integrity": "sha512-7i/dt5kGl7qR4gwPRD2biwD2/SvBn3O04J77XKFgL2OnZtQw+AG9wnuS/csmu80nPRHLYE9E41fyEiG8nhH6/Q==", + "hasInstallScript": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.0" + }, + "engines": { + "libvips": ">=8.15.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.4", + "@img/sharp-darwin-x64": "0.33.4", + "@img/sharp-libvips-darwin-arm64": "1.0.2", + "@img/sharp-libvips-darwin-x64": "1.0.2", + "@img/sharp-libvips-linux-arm": "1.0.2", + "@img/sharp-libvips-linux-arm64": "1.0.2", + "@img/sharp-libvips-linux-s390x": "1.0.2", + "@img/sharp-libvips-linux-x64": "1.0.2", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.2", + "@img/sharp-libvips-linuxmusl-x64": "1.0.2", + "@img/sharp-linux-arm": "0.33.4", + "@img/sharp-linux-arm64": "0.33.4", + "@img/sharp-linux-s390x": "0.33.4", + "@img/sharp-linux-x64": "0.33.4", + "@img/sharp-linuxmusl-arm64": "0.33.4", + "@img/sharp-linuxmusl-x64": "0.33.4", + "@img/sharp-wasm32": "0.33.4", + "@img/sharp-win32-ia32": "0.33.4", + "@img/sharp-win32-x64": "0.33.4" + } + }, + "node_modules/sharp/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -4465,6 +5000,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", diff --git a/package.json b/package.json index 255881070..062d87763 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "react": "^18", "react-dom": "^18", "react-hook-form": "^7.51.4", + "sharp": "^0.33.4", "styled-components": "^6.1.11" }, "devDependencies": { diff --git a/pages/index.tsx b/pages/index.tsx index e588fb25b..948877ab2 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -5,6 +5,7 @@ import { sectionDescription } from '../util/sectionDescription'; import { Button } from '../components/Button/Button'; import Link from 'next/link'; import { UserContext } from '@/contexts/UserContext'; +import Image from 'next/image'; function Main() { const [sectionList, setSectionList] = useState([]); @@ -29,7 +30,9 @@ function Main() { - + + 헤더 이미지 + diff --git a/styles/index.styled.ts b/styles/index.styled.ts index 700938e55..324c8dc69 100644 --- a/styles/index.styled.ts +++ b/styles/index.styled.ts @@ -61,14 +61,14 @@ export const Slogan_gradient = styled.span` `; export const Header__image = styled.div` - position: relative; - padding: 5rem 4rem 0 4rem; width: 120rem; - aspect-ratio: 2; + height: 59rem; + padding: 5rem 4rem 0; overflow: hidden; @media (max-width: 1199px) { width: 70rem; + height: 34rem; } @media (max-width: 768px) { @@ -76,10 +76,23 @@ export const Header__image = styled.div` } `; -export const HeaderImage = styled.img` +export const HeaderImage = styled.div` + position: relative; + height: 66rem; width: 100%; - border-radius: 2.5rem; - box-shadow: 0px 0.4rem 2.5rem 0px rgba(0, 0, 0, 0.08); + + img { + border-radius: 2.5rem; + box-shadow: 0px 0.4rem 2.5rem 0px rgba(0, 0, 0, 0.08); + } + + @media (max-width: 1199px) { + height: 38rem; + } + + @media (max-width: 768px) { + width: 100%; + } `; export const Main__contents = styled.div` From d64a7fe2c611050511ba2c7a8c636b948390684a Mon Sep 17 00:00:00 2001 From: sj0724 Date: Mon, 20 May 2024 14:22:08 +0900 Subject: [PATCH 03/34] =?UTF-8?q?fix:=20=EB=AA=A8=EB=8B=AC=EB=8F=99?= =?UTF-8?q?=EC=9E=91=EC=8B=9C=20=EB=8F=99=EC=9E=91=20=EB=A1=9C=EC=A7=81=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 --- components/FolderButton/FolderButton.tsx | 6 ++--- .../FolderButtonContainer.tsx | 8 +++--- .../FolderModalContainer/FolderModals.tsx | 25 ++++++++++++++++--- .../Modal/AddFolderModal/AddFolderModal.tsx | 21 ++++++++++++---- components/Modal/DeleteModal/DeleteModal.tsx | 14 +++++++++-- hooks/useGetFolderList.ts | 7 ++++-- pages/folder.tsx | 8 ++++-- 7 files changed, 65 insertions(+), 24 deletions(-) diff --git a/components/FolderButton/FolderButton.tsx b/components/FolderButton/FolderButton.tsx index cc0c2bbcb..a66ee832a 100644 --- a/components/FolderButton/FolderButton.tsx +++ b/components/FolderButton/FolderButton.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { Dispatch, SetStateAction } from 'react'; import * as S from './FolderButton.styled'; import { Folder } from '@/hooks/useGetFolderList'; @@ -13,9 +13,7 @@ function FolderButton({ isSelected: string; handleMenuClick: (index: number) => void; index: number; - setOnSelect: React.Dispatch< - React.SetStateAction<{ id: number; name: string }> - >; + setOnSelect: Dispatch>; }) { const changeFolder = () => { setOnSelect({ id: item.id, name: item.name }); diff --git a/components/FolderButtonContainer/FolderButtonContainer.tsx b/components/FolderButtonContainer/FolderButtonContainer.tsx index dcb0a95d9..033b91744 100644 --- a/components/FolderButtonContainer/FolderButtonContainer.tsx +++ b/components/FolderButtonContainer/FolderButtonContainer.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { Dispatch, SetStateAction, useState } from 'react'; import * as S from './FolderButtonContainer.styled'; import FolderButton from '../FolderButton/FolderButton'; import { useModal } from '../../contexts/ModalContext'; @@ -11,9 +11,7 @@ function FolderButtonContainer({ setOnSelect, }: { link: Folders; - setOnSelect: React.Dispatch< - React.SetStateAction<{ id: number; name: string }> - >; + setOnSelect: Dispatch>; }) { const [linkSelected, setLinkSelected] = useState([]); const [totalBtn, setTotalBtn] = useState(true); @@ -61,7 +59,7 @@ function FolderButtonContainer({ {modalState.addFolder && ( - + )} diff --git a/components/FolderModalContainer/FolderModals.tsx b/components/FolderModalContainer/FolderModals.tsx index 31548cb44..333f0a064 100644 --- a/components/FolderModalContainer/FolderModals.tsx +++ b/components/FolderModalContainer/FolderModals.tsx @@ -1,5 +1,5 @@ import Image from 'next/image'; -import { ReactNode } from 'react'; +import { Dispatch, ReactNode, SetStateAction } from 'react'; import * as S from './FolderModals.styled'; import { useModal } from '@/contexts/ModalContext'; import ModalPortal from '@/Portal'; @@ -26,8 +26,21 @@ function FolderIcon({ ); } -function FolderModals({ id, name }: { id: number; name: string }) { - const { modalState, openModal, closeModal } = useModal(); +function FolderModals({ + id, + name, + setOnSelect, +}: { + id: number; + name: string; + setOnSelect: Dispatch< + SetStateAction<{ + id: number; + name: string; + }> + >; +}) { + const { modalState, openModal } = useModal(); return ( @@ -52,7 +65,11 @@ function FolderModals({ id, name }: { id: number; name: string }) { )} {modalState.delete && ( - + )} diff --git a/components/Modal/AddFolderModal/AddFolderModal.tsx b/components/Modal/AddFolderModal/AddFolderModal.tsx index aec80485c..8262ea5d5 100644 --- a/components/Modal/AddFolderModal/AddFolderModal.tsx +++ b/components/Modal/AddFolderModal/AddFolderModal.tsx @@ -2,16 +2,27 @@ import * as S from '../EditModal/EditModal.styled'; import BaseModal from '../BaseModal/BaseModal'; import Input from '@/components/Input/Input'; import { postFolder } from '@/pages/api/api'; -import { useRouter } from 'next/router'; import { Controller, useForm } from 'react-hook-form'; +import { Dispatch, SetStateAction } from 'react'; +import { useModal } from '@/contexts/ModalContext'; -function AddFolderModal() { - const router = useRouter(); +function AddFolderModal({ + setOnSelect, +}: { + setOnSelect: Dispatch< + SetStateAction<{ + id: number; + name: string; + }> + >; +}) { const { handleSubmit, control } = useForm(); + const { closeModal } = useModal(); const addFolder = async (data: any) => { - await postFolder(data.folder); - router.reload(); + const result = await postFolder(data.folder); + setOnSelect({ id: 0, name: '' }); + closeModal('addFolder'); }; return ( diff --git a/components/Modal/DeleteModal/DeleteModal.tsx b/components/Modal/DeleteModal/DeleteModal.tsx index 5418aba93..e411bd817 100644 --- a/components/Modal/DeleteModal/DeleteModal.tsx +++ b/components/Modal/DeleteModal/DeleteModal.tsx @@ -1,22 +1,32 @@ -import React from 'react'; +import React, { Dispatch, SetStateAction } from 'react'; import * as S from './DeleteModal.styled'; import BaseModal from '../BaseModal/BaseModal'; import { deleteFolder } from '@/pages/api/api'; import { useRouter } from 'next/router'; +import { useModal } from '@/contexts/ModalContext'; function DeleteModal({ folderName, folderId, + setOnSelect, }: { folderName: string; folderId: number; + setOnSelect: Dispatch< + SetStateAction<{ + id: number; + name: string; + }> + >; }) { const router = useRouter(); + const { closeModal } = useModal(); const isDeleteModal = async (e: React.MouseEvent) => { e.preventDefault(); await deleteFolder(folderId); - router.reload(); + setOnSelect({ id: 0, name: '' }); + closeModal('delete'); }; return ( diff --git a/hooks/useGetFolderList.ts b/hooks/useGetFolderList.ts index 460572b3f..64eb61a91 100644 --- a/hooks/useGetFolderList.ts +++ b/hooks/useGetFolderList.ts @@ -16,7 +16,10 @@ export interface Folder { export interface Folders extends Array {} -function useGetFolderList(userId: string) { +function useGetFolderList( + userId: string, + onSelect: { id: number; name: string } +) { const [link, setLink] = useState([]); useEffect(() => { @@ -27,7 +30,7 @@ function useGetFolderList(userId: string) { }; loadFolderList(); } - }, [userId]); + }, [userId, onSelect]); return { link, diff --git a/pages/folder.tsx b/pages/folder.tsx index 36d26a5ac..c007215c0 100644 --- a/pages/folder.tsx +++ b/pages/folder.tsx @@ -21,7 +21,7 @@ function Folder() { }); const [searchKeyword, setSearchKeyWord] = useState(''); const { linkList, loading } = useGetFolder(id, searchKeyword, onSelect.id); - const { link } = useGetFolderList(id); + const { link } = useGetFolderList(id, onSelect); const [toggleInput, setToggleInput] = useState(true); const { modalState, openModal }: ContextValue = useModal(); const obsRef = useRef(null); @@ -81,7 +81,11 @@ function Folder() { {onSelect.name ? onSelect.name : '전체'} {onSelect.name && ( - + )} From c10ef9a741d8e27da22e1580dd22acf057d7bd39 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Tue, 21 May 2024 11:36:40 +0900 Subject: [PATCH 04/34] =?UTF-8?q?fix:=20axios=20intercepros=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9,=20=ED=86=A0=ED=81=B0=20=EC=9E=90=EB=8F=99=20?= =?UTF-8?q?=EA=B8=B0=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Card/Card.tsx | 23 ++++++--- components/Modal/DeleteModal/DeleteModal.tsx | 2 - pages/api/api.ts | 52 ++++++++------------ pages/folder/[id].tsx | 13 +++++ pages/{folder.tsx => folder/index.tsx} | 33 +++++++------ 5 files changed, 68 insertions(+), 55 deletions(-) create mode 100644 pages/folder/[id].tsx rename pages/{folder.tsx => folder/index.tsx} (78%) diff --git a/components/Card/Card.tsx b/components/Card/Card.tsx index ec2731f4a..108ca6c58 100644 --- a/components/Card/Card.tsx +++ b/components/Card/Card.tsx @@ -9,9 +9,14 @@ import Link from 'next/link'; function Card({ item, setUrl, + onSelect, }: { item: LinkData; setUrl: Dispatch>; + onSelect?: { + id: number; + name: string; + }; }) { const [createdAt, setCreatedAt] = useState({ time: 0, result: '' }); const [fullDate, setFullDate] = useState(''); @@ -49,14 +54,16 @@ function Card({ )} - { - setKebabView(!kebabView); - e.preventDefault(); - }} - /> + {onSelect && onSelect.name && ( + { + setKebabView(!kebabView); + e.preventDefault(); + }} + /> + )} {createdText} {description ? description : url} diff --git a/components/Modal/DeleteModal/DeleteModal.tsx b/components/Modal/DeleteModal/DeleteModal.tsx index e411bd817..772967a16 100644 --- a/components/Modal/DeleteModal/DeleteModal.tsx +++ b/components/Modal/DeleteModal/DeleteModal.tsx @@ -2,7 +2,6 @@ import React, { Dispatch, SetStateAction } from 'react'; import * as S from './DeleteModal.styled'; import BaseModal from '../BaseModal/BaseModal'; import { deleteFolder } from '@/pages/api/api'; -import { useRouter } from 'next/router'; import { useModal } from '@/contexts/ModalContext'; function DeleteModal({ @@ -19,7 +18,6 @@ function DeleteModal({ }> >; }) { - const router = useRouter(); const { closeModal } = useModal(); const isDeleteModal = async (e: React.MouseEvent) => { diff --git a/pages/api/api.ts b/pages/api/api.ts index 9ec76c152..ef7c47cb2 100644 --- a/pages/api/api.ts +++ b/pages/api/api.ts @@ -1,5 +1,18 @@ import axios from '../../instance/instance'; +axios.interceptors.request.use( + (config) => { + const accessToken = localStorage.getItem('token'); + config.headers['Authorization'] = accessToken; + + return config; + }, + (error) => { + console.log(error); + return Promise.reject(error); + } +); + export async function getSampleUser() { try { const { data } = await axios.get('/sample/user'); @@ -130,18 +143,9 @@ export async function postSignUp(id: string, password: string) { export async function postFolder(name: string) { try { - const token = localStorage.getItem('token'); - const { data } = await axios.post( - '/folders', - { - name: name, - }, - { - headers: { - Authorization: token, - }, - } - ); + const { data } = await axios.post('/folders', { + name: name, + }); return data; } catch (error) { console.error('Error fetching post folder:', error); @@ -164,19 +168,10 @@ export async function deleteFolder(folderId: number) { export async function postLink(folderId: number, url: string) { try { - const token = localStorage.getItem('token'); - const { data } = await axios.post( - '/links', - { - url: url, - folderId: folderId, - }, - { - headers: { - Authorization: token, - }, - } - ); + const { data } = await axios.post('/links', { + url: url, + folderId: folderId, + }); return data; } catch (error) { alert('url과 폴더를 지정해주세요!'); @@ -186,12 +181,7 @@ export async function postLink(folderId: number, url: string) { export async function deleteLink(linkId: number) { try { - const token = localStorage.getItem('token'); - const { data } = await axios.delete(`/links/${linkId}`, { - headers: { - Authorization: token, - }, - }); + const { data } = await axios.delete(`/links/${linkId}`); return data; } catch (error) { console.error('Error fetching post folder:', error); diff --git a/pages/folder/[id].tsx b/pages/folder/[id].tsx new file mode 100644 index 000000000..4d495d2d4 --- /dev/null +++ b/pages/folder/[id].tsx @@ -0,0 +1,13 @@ +import { useRouter } from 'next/router'; + +export default function ProductsItem() { + const router = useRouter(); + + console.log(router); + return ( + <> +

{router.pathname}

+

{router.query.id}

+ + ); +} diff --git a/pages/folder.tsx b/pages/folder/index.tsx similarity index 78% rename from pages/folder.tsx rename to pages/folder/index.tsx index c007215c0..55bc93acb 100644 --- a/pages/folder.tsx +++ b/pages/folder/index.tsx @@ -1,15 +1,15 @@ import { useContext } from 'react'; import { useEffect, useRef, useState } from 'react'; -import * as S from '../styles/folder.styled'; -import SearchBar from '../components/SearchBar/SearchBar'; -import ContentsContainer from '../components/ContentsContainer'; -import Card from '../components/Card/Card'; -import useGetFolder from '../hooks/useGetFolder'; -import useGetFolderList from '../hooks/useGetFolderList'; -import FolderButtonContainer from '../components/FolderButtonContainer/FolderButtonContainer'; -import { ContextValue, useModal } from '../contexts/ModalContext'; -import AddModal from '../components/Modal/AddModal/AddModal'; -import ModalPortal from '../Portal'; +import * as S from '../../styles/folder.styled'; +import SearchBar from '../../components/SearchBar/SearchBar'; +import ContentsContainer from '../../components/ContentsContainer'; +import Card from '../../components/Card/Card'; +import useGetFolder from '../../hooks/useGetFolder'; +import useGetFolderList from '../../hooks/useGetFolderList'; +import FolderButtonContainer from '../../components/FolderButtonContainer/FolderButtonContainer'; +import { useModal } from '../../contexts/ModalContext'; +import AddModal from '../../components/Modal/AddModal/AddModal'; +import ModalPortal from '../../Portal'; import { UserContext } from '@/contexts/UserContext'; import FolderModals from '@/components/FolderModalContainer/FolderModals'; @@ -20,13 +20,13 @@ function Folder() { name: '', }); const [searchKeyword, setSearchKeyWord] = useState(''); + const [url, setUrl] = useState(''); + const [toggleInput, setToggleInput] = useState(true); const { linkList, loading } = useGetFolder(id, searchKeyword, onSelect.id); const { link } = useGetFolderList(id, onSelect); - const [toggleInput, setToggleInput] = useState(true); - const { modalState, openModal }: ContextValue = useModal(); + const { modalState, openModal } = useModal(); const obsRef = useRef(null); const inputRef = useRef(null); - const [url, setUrl] = useState(''); const handleObserver = (entries: IntersectionObserverEntry[]) => { entries.forEach((entry) => { @@ -91,7 +91,12 @@ function Folder() { {linkList.length > 0 ? ( linkList.map((item) => ( - + )) ) : ( 저장된 링크가 없습니다. From f8122ea942b862086d25e2a857a91947d1ab97bb Mon Sep 17 00:00:00 2001 From: sj0724 Date: Tue, 21 May 2024 21:41:11 +0900 Subject: [PATCH 05/34] =?UTF-8?q?feat:=20=ED=8F=B4=EB=8D=94=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=EC=8B=9C=20=EC=BF=BC=EB=A6=AC=20=EB=B3=80=EA=B2=BD,?= =?UTF-8?q?=20=ED=80=B4=EB=A6=AC=EA=B0=92=20=EC=82=AC=EC=9A=A9=ED=95=B4?= =?UTF-8?q?=EC=84=9C=20=ED=8F=B4=EB=8D=94=20=EB=A7=81=ED=81=AC=20=EB=A1=9C?= =?UTF-8?q?=EB=94=A9,=20=EC=A1=B4=EC=9E=AC=ED=95=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EB=8A=94=20=ED=8F=B4=EB=8D=94=20=EC=9A=94=EC=B2=AD=EC=8B=9C=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {pages/api => api}/api.ts | 8 +- components/Card/Card.tsx | 2 +- components/FolderButton/FolderButton.tsx | 11 +- .../FolderButtonContainer.tsx | 21 +-- .../FolderModalContainer/FolderModals.tsx | 4 +- .../Modal/AddFolderModal/AddFolderModal.tsx | 8 +- components/Modal/AddModal/AddModal.tsx | 2 +- .../Modal/DeleteLinkModal/DeleteLinkModal.tsx | 2 +- components/Modal/DeleteModal/DeleteModal.tsx | 8 +- hooks/useGetFolder.ts | 4 +- hooks/useGetFolderList.ts | 11 +- hooks/useGetUser.ts | 2 +- next.config.js | 1 - pages/_app.tsx | 2 +- pages/folder/[folderId].tsx | 132 ++++++++++++++++++ pages/folder/[id].tsx | 13 -- pages/folder/index.tsx | 4 +- pages/shared.tsx | 2 +- pages/signin.tsx | 2 +- pages/signup.tsx | 2 +- styles/folder.styled.ts | 2 +- 21 files changed, 183 insertions(+), 60 deletions(-) rename {pages/api => api}/api.ts (96%) create mode 100644 pages/folder/[folderId].tsx delete mode 100644 pages/folder/[id].tsx diff --git a/pages/api/api.ts b/api/api.ts similarity index 96% rename from pages/api/api.ts rename to api/api.ts index ef7c47cb2..b71a3e5f2 100644 --- a/pages/api/api.ts +++ b/api/api.ts @@ -1,4 +1,4 @@ -import axios from '../../instance/instance'; +import axios from '../instance/instance'; axios.interceptors.request.use( (config) => { @@ -62,7 +62,7 @@ export async function getFolder(id: string) { } } -export async function getFolderList(id: string, folderId: number) { +export async function getFolderList(id: string, folderId: string) { if (folderId) { try { const query = `/${id}/links?folderId=${folderId}`; @@ -146,13 +146,13 @@ export async function postFolder(name: string) { const { data } = await axios.post('/folders', { name: name, }); - return data; + return data.data; } catch (error) { console.error('Error fetching post folder:', error); } } -export async function deleteFolder(folderId: number) { +export async function deleteFolder(folderId: string) { try { const token = localStorage.getItem('token'); const { data } = await axios.delete(`/folders/${folderId}`, { diff --git a/components/Card/Card.tsx b/components/Card/Card.tsx index 108ca6c58..310394bc0 100644 --- a/components/Card/Card.tsx +++ b/components/Card/Card.tsx @@ -14,7 +14,7 @@ function Card({ item: LinkData; setUrl: Dispatch>; onSelect?: { - id: number; + id: string; name: string; }; }) { diff --git a/components/FolderButton/FolderButton.tsx b/components/FolderButton/FolderButton.tsx index a66ee832a..a9135b884 100644 --- a/components/FolderButton/FolderButton.tsx +++ b/components/FolderButton/FolderButton.tsx @@ -1,6 +1,7 @@ import React, { Dispatch, SetStateAction } from 'react'; import * as S from './FolderButton.styled'; import { Folder } from '@/hooks/useGetFolderList'; +import Link from 'next/link'; function FolderButton({ item, @@ -13,7 +14,7 @@ function FolderButton({ isSelected: string; handleMenuClick: (index: number) => void; index: number; - setOnSelect: Dispatch>; + setOnSelect: Dispatch>; }) { const changeFolder = () => { setOnSelect({ id: item.id, name: item.name }); @@ -21,9 +22,11 @@ function FolderButton({ }; return ( - - {item.name} - + + + {item.name} + + ); } diff --git a/components/FolderButtonContainer/FolderButtonContainer.tsx b/components/FolderButtonContainer/FolderButtonContainer.tsx index 033b91744..f7454e177 100644 --- a/components/FolderButtonContainer/FolderButtonContainer.tsx +++ b/components/FolderButtonContainer/FolderButtonContainer.tsx @@ -1,17 +1,18 @@ -import { Dispatch, SetStateAction, useState } from 'react'; +import { Dispatch, SetStateAction, useEffect, useState } from 'react'; import * as S from './FolderButtonContainer.styled'; import FolderButton from '../FolderButton/FolderButton'; import { useModal } from '../../contexts/ModalContext'; import { Folders } from '../../hooks/useGetFolderList'; import ModalPortal from '@/Portal'; import AddFolderModal from '../Modal/AddFolderModal/AddFolderModal'; +import Link from 'next/link'; function FolderButtonContainer({ link, setOnSelect, }: { link: Folders; - setOnSelect: Dispatch>; + setOnSelect: Dispatch>; }) { const [linkSelected, setLinkSelected] = useState([]); const [totalBtn, setTotalBtn] = useState(true); @@ -27,19 +28,21 @@ function FolderButtonContainer({ const handleClickTotalButton = () => { const totalArr: string[] = new Array(link.length).fill('white'); setLinkSelected(totalArr); - setOnSelect({ id: 0, name: '' }); + setOnSelect({ id: '', name: '' }); setTotalBtn(true); }; return ( - - 전체 - + + + 전체 + + {link ? link.map((item, index: number) => ( >; diff --git a/components/Modal/AddFolderModal/AddFolderModal.tsx b/components/Modal/AddFolderModal/AddFolderModal.tsx index 8262ea5d5..a8ad9c7c4 100644 --- a/components/Modal/AddFolderModal/AddFolderModal.tsx +++ b/components/Modal/AddFolderModal/AddFolderModal.tsx @@ -1,27 +1,29 @@ import * as S from '../EditModal/EditModal.styled'; import BaseModal from '../BaseModal/BaseModal'; import Input from '@/components/Input/Input'; -import { postFolder } from '@/pages/api/api'; +import { postFolder } from '@/api/api'; import { Controller, useForm } from 'react-hook-form'; import { Dispatch, SetStateAction } from 'react'; import { useModal } from '@/contexts/ModalContext'; +import { useRouter } from 'next/router'; function AddFolderModal({ setOnSelect, }: { setOnSelect: Dispatch< SetStateAction<{ - id: number; + id: string; name: string; }> >; }) { const { handleSubmit, control } = useForm(); const { closeModal } = useModal(); + const router = useRouter(); const addFolder = async (data: any) => { const result = await postFolder(data.folder); - setOnSelect({ id: 0, name: '' }); + router.push(`/folder/${result[0].id}`); closeModal('addFolder'); }; diff --git a/components/Modal/AddModal/AddModal.tsx b/components/Modal/AddModal/AddModal.tsx index fbf1224c9..1ccd558e7 100644 --- a/components/Modal/AddModal/AddModal.tsx +++ b/components/Modal/AddModal/AddModal.tsx @@ -4,7 +4,7 @@ import BaseModal from '../BaseModal/BaseModal'; import { Folder, Folders } from '../../../hooks/useGetFolderList'; import { Button } from '../../Button/Button'; import Image from 'next/image'; -import { postLink } from '@/pages/api/api'; +import { postLink } from '@/api/api'; import { useRouter } from 'next/router'; import { useModal } from '@/contexts/ModalContext'; diff --git a/components/Modal/DeleteLinkModal/DeleteLinkModal.tsx b/components/Modal/DeleteLinkModal/DeleteLinkModal.tsx index bb24f6c04..b117a4860 100644 --- a/components/Modal/DeleteLinkModal/DeleteLinkModal.tsx +++ b/components/Modal/DeleteLinkModal/DeleteLinkModal.tsx @@ -1,7 +1,7 @@ import React from 'react'; import * as S from '../DeleteModal/DeleteModal.styled'; import BaseModal from '../BaseModal/BaseModal'; -import { deleteLink } from '@/pages/api/api'; +import { deleteLink } from '@/api/api'; import { useRouter } from 'next/router'; function DeleteLinkModal({ id }: { id: number }) { diff --git a/components/Modal/DeleteModal/DeleteModal.tsx b/components/Modal/DeleteModal/DeleteModal.tsx index 772967a16..77692afce 100644 --- a/components/Modal/DeleteModal/DeleteModal.tsx +++ b/components/Modal/DeleteModal/DeleteModal.tsx @@ -1,7 +1,7 @@ import React, { Dispatch, SetStateAction } from 'react'; import * as S from './DeleteModal.styled'; import BaseModal from '../BaseModal/BaseModal'; -import { deleteFolder } from '@/pages/api/api'; +import { deleteFolder } from '@/api/api'; import { useModal } from '@/contexts/ModalContext'; function DeleteModal({ @@ -10,10 +10,10 @@ function DeleteModal({ setOnSelect, }: { folderName: string; - folderId: number; + folderId: string; setOnSelect: Dispatch< SetStateAction<{ - id: number; + id: string; name: string; }> >; @@ -23,7 +23,7 @@ function DeleteModal({ const isDeleteModal = async (e: React.MouseEvent) => { e.preventDefault(); await deleteFolder(folderId); - setOnSelect({ id: 0, name: '' }); + window.location.href = '/folder'; closeModal('delete'); }; diff --git a/hooks/useGetFolder.ts b/hooks/useGetFolder.ts index 43ac65b16..00a26f5eb 100644 --- a/hooks/useGetFolder.ts +++ b/hooks/useGetFolder.ts @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { getFolderList } from '../pages/api/api'; +import { getFolderList } from '../api/api'; export type LinkData = { id: number; @@ -14,7 +14,7 @@ export type LinkData = { export interface Links extends Array {} -function useGetFolder(id: string, searchKeyword: string, folderId: number) { +function useGetFolder(id: string, searchKeyword: string, folderId: string) { const [linkList, setLinkList] = useState([]); const [loading, setLoading] = useState(false); diff --git a/hooks/useGetFolderList.ts b/hooks/useGetFolderList.ts index 64eb61a91..445716038 100644 --- a/hooks/useGetFolderList.ts +++ b/hooks/useGetFolderList.ts @@ -1,12 +1,12 @@ import { useEffect, useState } from 'react'; -import { getFolder } from '../pages/api/api'; +import { getFolder } from '../api/api'; type Like = { count: number; }; export interface Folder { - id: number; + id: string; created_at: Date; name: string; user_id: number; @@ -16,10 +16,7 @@ export interface Folder { export interface Folders extends Array {} -function useGetFolderList( - userId: string, - onSelect: { id: number; name: string } -) { +function useGetFolderList(userId: string, folderId?: string) { const [link, setLink] = useState([]); useEffect(() => { @@ -30,7 +27,7 @@ function useGetFolderList( }; loadFolderList(); } - }, [userId, onSelect]); + }, [userId, folderId]); return { link, diff --git a/hooks/useGetUser.ts b/hooks/useGetUser.ts index ac53759a1..0a332db0c 100644 --- a/hooks/useGetUser.ts +++ b/hooks/useGetUser.ts @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { getUser } from '../pages/api/api'; +import { getUser } from '../api/api'; export interface User { id: string; diff --git a/next.config.js b/next.config.js index 18744343d..59874acc9 100644 --- a/next.config.js +++ b/next.config.js @@ -4,7 +4,6 @@ module.exports = { compiler: { styledComponents: true, }, - assetPrefix: '.', experimental: { forceSwcTransforms: true, }, diff --git a/pages/_app.tsx b/pages/_app.tsx index b734455dd..1e6a25727 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -6,7 +6,7 @@ import '@/styles/globals.css'; import type { AppProps } from 'next/app'; import Head from 'next/head'; import { useEffect, useState } from 'react'; -import { getUser } from './api/api'; +import { getUser } from '../api/api'; import { User } from '@/hooks/useGetUser'; export default function App({ Component, pageProps }: AppProps) { diff --git a/pages/folder/[folderId].tsx b/pages/folder/[folderId].tsx new file mode 100644 index 000000000..ecdb493a8 --- /dev/null +++ b/pages/folder/[folderId].tsx @@ -0,0 +1,132 @@ +import { useContext } from 'react'; +import { useEffect, useRef, useState } from 'react'; +import * as S from '../../styles/folder.styled'; +import SearchBar from '../../components/SearchBar/SearchBar'; +import ContentsContainer from '../../components/ContentsContainer'; +import Card from '../../components/Card/Card'; +import useGetFolder from '../../hooks/useGetFolder'; +import useGetFolderList from '../../hooks/useGetFolderList'; +import FolderButtonContainer from '../../components/FolderButtonContainer/FolderButtonContainer'; +import { useModal } from '../../contexts/ModalContext'; +import AddModal from '../../components/Modal/AddModal/AddModal'; +import ModalPortal from '../../Portal'; +import { UserContext } from '@/contexts/UserContext'; +import FolderModals from '@/components/FolderModalContainer/FolderModals'; +import { useRouter } from 'next/router'; + +function Folder() { + const id = useContext(UserContext); + const [onSelect, setOnSelect] = useState({ + id: '', + name: '', + }); + const [searchKeyword, setSearchKeyWord] = useState(''); + const [url, setUrl] = useState(''); + const [toggleInput, setToggleInput] = useState(true); + const [wrongFolder, setWrongFolder] = useState(false); + const router = useRouter(); + const folderId = router.query.folderId as string; + const { linkList, loading } = useGetFolder(id, searchKeyword, folderId); + const { link } = useGetFolderList(id, folderId); + const { modalState, openModal } = useModal(); + const obsRef = useRef(null); + const inputRef = useRef(null); + + const handleObserver = (entries: IntersectionObserverEntry[]) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + setToggleInput(false); + return; + } else { + setToggleInput(true); + return; + } + }); + }; + + useEffect(() => { + const observer = new IntersectionObserver(handleObserver); + if (!loading && obsRef.current) observer.observe(obsRef.current); + return () => { + observer.disconnect(); + }; + }, [loading]); + + useEffect(() => { + for (let i = 0; i < link.length; i++) { + setWrongFolder(true); + if (link[i].id == folderId) { + setOnSelect({ id: folderId, name: link[i].name }); + setWrongFolder(false); + break; + } + } + }, [link, folderId]); + + if (wrongFolder) { + return 존재하지 않는 폴더입니다!; + } + + return ( + <> +
+ + + + + + { + openModal('add'); + if (inputRef.current) { + setUrl(inputRef.current.value); + } + }} + > + 추가하기 + + + + + + + {searchKeyword && ( + +

{searchKeyword}

으로 검색한 결과입니다. +
+ )} + + + {onSelect.name} + + + + {linkList.length > 0 ? ( + linkList.map((item) => ( + + )) + ) : ( + 저장된 링크가 없습니다. + )} + + {modalState.add && inputRef.current && ( + + + + )} +
+ + ); +} + +export default Folder; diff --git a/pages/folder/[id].tsx b/pages/folder/[id].tsx deleted file mode 100644 index 4d495d2d4..000000000 --- a/pages/folder/[id].tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { useRouter } from 'next/router'; - -export default function ProductsItem() { - const router = useRouter(); - - console.log(router); - return ( - <> -

{router.pathname}

-

{router.query.id}

- - ); -} diff --git a/pages/folder/index.tsx b/pages/folder/index.tsx index 55bc93acb..9aba0f584 100644 --- a/pages/folder/index.tsx +++ b/pages/folder/index.tsx @@ -16,14 +16,14 @@ import FolderModals from '@/components/FolderModalContainer/FolderModals'; function Folder() { const id = useContext(UserContext); const [onSelect, setOnSelect] = useState({ - id: 0, + id: '', name: '', }); const [searchKeyword, setSearchKeyWord] = useState(''); const [url, setUrl] = useState(''); const [toggleInput, setToggleInput] = useState(true); const { linkList, loading } = useGetFolder(id, searchKeyword, onSelect.id); - const { link } = useGetFolderList(id, onSelect); + const { link } = useGetFolderList(id); const { modalState, openModal } = useModal(); const obsRef = useRef(null); const inputRef = useRef(null); diff --git a/pages/shared.tsx b/pages/shared.tsx index 232ca09cf..23db7ba30 100644 --- a/pages/shared.tsx +++ b/pages/shared.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; import * as S from '../styles/shared.styled'; -import { getSampleFolder } from './api/api'; +import { getSampleFolder } from '../api/api'; import Card from '../components/Card/Card'; import SearchBar from '../components/SearchBar/SearchBar'; diff --git a/pages/signin.tsx b/pages/signin.tsx index b3b436c7f..3c2af4f2d 100644 --- a/pages/signin.tsx +++ b/pages/signin.tsx @@ -4,7 +4,7 @@ import Input from '@/components/Input/Input'; import Link from 'next/link'; import Image from 'next/image'; import { Button } from '@/components/Button/Button'; -import { postSignIn } from './api/api'; +import { postSignIn } from '../api/api'; import { Controller, useForm } from 'react-hook-form'; import { emailPattern } from '@/util/util'; diff --git a/pages/signup.tsx b/pages/signup.tsx index e4c8fb91b..def9460e3 100644 --- a/pages/signup.tsx +++ b/pages/signup.tsx @@ -4,7 +4,7 @@ import Input from '@/components/Input/Input'; import Link from 'next/link'; import Image from 'next/image'; import { Button } from '@/components/Button/Button'; -import { postCheckEmail, postSignUp } from './api/api'; +import { postCheckEmail, postSignUp } from '../api/api'; import { Controller, useForm } from 'react-hook-form'; import { emailPattern } from '@/util/util'; diff --git a/styles/folder.styled.ts b/styles/folder.styled.ts index 6cd89eb11..135be3e29 100644 --- a/styles/folder.styled.ts +++ b/styles/folder.styled.ts @@ -15,7 +15,7 @@ export const AddButton = styled(Cta)` `; export const EmptyFolder = styled.div` - height: 30rem; + height: 50vh; font-size: 1.6rem; margin: 0 auto; display: flex; From 3113144a24086360d91a4a429e2b8fb12d4e78d4 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Wed, 22 May 2024 21:27:56 +0900 Subject: [PATCH 06/34] =?UTF-8?q?feat:=20kebab=20=EC=99=B8=EB=B6=80=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=EC=8B=9C=20kebab=20=EB=8B=AB=EA=B8=B0=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 --- Portal.tsx | 12 +------ api/api.ts | 2 +- components/Card/Card.tsx | 35 ++++++++++++++----- components/Input/Input.tsx | 1 - components/KebabMenu/KebabMenu.styled.ts | 1 - components/KebabMenu/KebabMenu.tsx | 31 ++++++++++++---- components/Modal/AddModal/AddModal.tsx | 8 ++--- .../Modal/BaseModal/BaseModal.styled.ts | 2 +- components/Modal/BaseModal/BaseModal.tsx | 2 +- .../Modal/DeleteLinkModal/DeleteLinkModal.tsx | 4 ++- .../Modal/DeleteModal/DeleteModal.styled.ts | 7 ++++ pages/signin.tsx | 2 -- pages/signup.tsx | 5 +-- 13 files changed, 70 insertions(+), 42 deletions(-) diff --git a/Portal.tsx b/Portal.tsx index fb6fcb585..9b1c597d3 100644 --- a/Portal.tsx +++ b/Portal.tsx @@ -2,23 +2,13 @@ import React, { ReactElement, useEffect, useState } from 'react'; import { createPortal } from 'react-dom'; const ModalPortal = ({ children }: { children: ReactElement }) => { - const [mounted, setMounted] = useState(false); const [portalElement, setPortalElement] = useState(null); useEffect(() => { setPortalElement(document.getElementById('modal')); }, []); - useEffect(() => { - setMounted(true); - return () => setMounted(false); - }, []); - - return ( - <> - {mounted && portalElement ? createPortal(children, portalElement) : null} - - ); + return <>{portalElement ? createPortal(children, portalElement) : null}; }; export default ModalPortal; diff --git a/api/api.ts b/api/api.ts index b71a3e5f2..769038f90 100644 --- a/api/api.ts +++ b/api/api.ts @@ -166,7 +166,7 @@ export async function deleteFolder(folderId: string) { } } -export async function postLink(folderId: number, url: string) { +export async function postLink(folderId: string, url: string) { try { const { data } = await axios.post('/links', { url: url, diff --git a/components/Card/Card.tsx b/components/Card/Card.tsx index 310394bc0..b72486c5a 100644 --- a/components/Card/Card.tsx +++ b/components/Card/Card.tsx @@ -5,6 +5,9 @@ import KebabMenu from '../KebabMenu/KebabMenu'; import { LinkData } from '../../hooks/useGetFolder'; import Image from 'next/image'; import Link from 'next/link'; +import { useModal } from '@/contexts/ModalContext'; +import ModalPortal from '@/Portal'; +import DeleteLinkModal from '../Modal/DeleteLinkModal/DeleteLinkModal'; function Card({ item, @@ -24,15 +27,21 @@ function Card({ const [kebabView, setKebabView] = useState(false); const [like, setLike] = useState(false); const { url, description, id } = item; + const { modalState } = useModal(); const createdText = `${createdAt.time} ${createdAt.result} ago`; + const handleKebab = (e: React.MouseEvent) => { + setKebabView(!kebabView); + e.preventDefault(); + }; + useEffect(() => { const nowDate = new Date(); - const createdate = new Date(item.created_at); - const date = (Number(nowDate) - Number(createdate)) / 1000; + const createDate = new Date(item.created_at); + const date = (Number(nowDate) - Number(createDate)) / 1000; setCreatedAt(calculateDate(date)); - setFullDate(changeDate(createdate)); + setFullDate(changeDate(createDate)); }, [item]); return ( @@ -58,10 +67,7 @@ function Card({ { - setKebabView(!kebabView); - e.preventDefault(); - }} + onClick={handleKebab} /> )} {createdText} @@ -70,8 +76,21 @@ function Card({
{fullDate}
- {kebabView && } + {kebabView && ( + + )} + {modalState.deleteLink && ( + + + + )} ); } diff --git a/components/Input/Input.tsx b/components/Input/Input.tsx index 595cf78af..33ad42574 100644 --- a/components/Input/Input.tsx +++ b/components/Input/Input.tsx @@ -11,7 +11,6 @@ export interface InputProps { type: string; size: 'sm' | 'md' | 'lg'; field: ControllerRenderProps; - id: string; error: FieldError | undefined; } diff --git a/components/KebabMenu/KebabMenu.styled.ts b/components/KebabMenu/KebabMenu.styled.ts index ee8d9ea24..b55778ef5 100644 --- a/components/KebabMenu/KebabMenu.styled.ts +++ b/components/KebabMenu/KebabMenu.styled.ts @@ -11,7 +11,6 @@ export const ModalBody = styled.div` align-items: center; justify-content: center; background: #fff; - z-index: 10; `; export const ModalButton = styled.div` diff --git a/components/KebabMenu/KebabMenu.tsx b/components/KebabMenu/KebabMenu.tsx index f0b162db8..9828c1f0f 100644 --- a/components/KebabMenu/KebabMenu.tsx +++ b/components/KebabMenu/KebabMenu.tsx @@ -1,4 +1,4 @@ -import React, { Dispatch, SetStateAction, useRef } from 'react'; +import React, { Dispatch, SetStateAction, useEffect, useRef } from 'react'; import { useModal } from '@/contexts/ModalContext'; import * as S from './KebabMenu.styled'; import ModalPortal from '@/Portal'; @@ -8,13 +8,17 @@ function KebabMenu({ url, id, setUrl, + setKebabView, + kebabView, }: { url: string; id: number; setUrl: Dispatch>; + setKebabView: Dispatch>; + kebabView: boolean; }) { const kebabRef = useRef(null); - const { modalState, openModal } = useModal(); + const { openModal } = useModal(); const handleAddKebab = (e: React.MouseEvent) => { e.preventDefault(); @@ -29,17 +33,30 @@ function KebabMenu({ openModal('deleteLink'); }; + useEffect(() => { + function handleClickOutside(e: MouseEvent) { + if ( + kebabView && + kebabRef.current && + !kebabRef.current.contains(e.target as Node) + ) { + setKebabView(!kebabView); + console.log(e.target as Node); + } + } + + document.addEventListener('mousedown', handleClickOutside); + return () => { + document.removeEventListener('mousedown', handleClickOutside); + }; + }, [setKebabView, kebabView]); + return ( <> 삭제하기 폴더에 추가 - {modalState.deleteLink && ( - - - - )} ); } diff --git a/components/Modal/AddModal/AddModal.tsx b/components/Modal/AddModal/AddModal.tsx index 1ccd558e7..dd39daf16 100644 --- a/components/Modal/AddModal/AddModal.tsx +++ b/components/Modal/AddModal/AddModal.tsx @@ -18,8 +18,8 @@ function FolderButton({ item: Folder; $isSelected: string; index: number; - handleMenuClick: (index: number, folderId: number) => void; - folderId: number; + handleMenuClick: (index: number, folderId: string) => void; + folderId: string; }) { return ( ([]); - const [selectedId, setSelectedId] = useState(0); + const [selectedId, setSelectedId] = useState(''); const { openModal, closeModal } = useModal(); const router = useRouter(); - const handleMenuClick = (index: number, folderId: number) => { + const handleMenuClick = (index: number, folderId: string) => { const booleanArr: string[] = new Array(link.length).fill('none'); booleanArr[index] = 'select'; setFolderSelected(booleanArr); diff --git a/components/Modal/BaseModal/BaseModal.styled.ts b/components/Modal/BaseModal/BaseModal.styled.ts index 052c48201..6ce876e0f 100644 --- a/components/Modal/BaseModal/BaseModal.styled.ts +++ b/components/Modal/BaseModal/BaseModal.styled.ts @@ -35,5 +35,5 @@ export const CloseIcon = styled.img` right: 1.6rem; width: 2.4rem; height: 2.4rem; - z-index: 10; + z-index: 20; `; diff --git a/components/Modal/BaseModal/BaseModal.tsx b/components/Modal/BaseModal/BaseModal.tsx index 6e9b1eb6f..1daac8811 100644 --- a/components/Modal/BaseModal/BaseModal.tsx +++ b/components/Modal/BaseModal/BaseModal.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import * as S from './BaseModal.styled'; import { useModal } from '@/contexts/ModalContext'; diff --git a/components/Modal/DeleteLinkModal/DeleteLinkModal.tsx b/components/Modal/DeleteLinkModal/DeleteLinkModal.tsx index b117a4860..5c6428fe4 100644 --- a/components/Modal/DeleteLinkModal/DeleteLinkModal.tsx +++ b/components/Modal/DeleteLinkModal/DeleteLinkModal.tsx @@ -17,7 +17,9 @@ function DeleteLinkModal({ id }: { id: number }) { return ( - 링크 삭제 + + 링크 삭제 + 삭제하기 diff --git a/components/Modal/DeleteModal/DeleteModal.styled.ts b/components/Modal/DeleteModal/DeleteModal.styled.ts index f5bb1d5b9..4c01edad7 100644 --- a/components/Modal/DeleteModal/DeleteModal.styled.ts +++ b/components/Modal/DeleteModal/DeleteModal.styled.ts @@ -1,6 +1,13 @@ import { Cta } from '@/components/Button/Button.styled'; import styled from 'styled-components'; +export const Header = styled.div` + display: flex; + flex-direction: column; + align-items: center; + gap: 0.8rem; +`; + export const Title = styled.p` font-size: 2rem; font-style: normal; diff --git a/pages/signin.tsx b/pages/signin.tsx index 3c2af4f2d..f18e6da80 100644 --- a/pages/signin.tsx +++ b/pages/signin.tsx @@ -51,7 +51,6 @@ function SignIn() { }} render={({ field, fieldState: { error } }) => ( ( ( ( ( Date: Thu, 23 May 2024 14:17:53 +0900 Subject: [PATCH 07/34] =?UTF-8?q?fix:=20=EB=8F=99=EC=A0=81=20=EB=9D=BC?= =?UTF-8?q?=EC=9A=B0=ED=8C=85,=20=EC=98=B5=EC=85=94=EB=84=90=20=EC=84=B8?= =?UTF-8?q?=EA=B7=B8=EB=A8=BC=ED=8A=B8=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FolderButtonContainer.tsx | 3 +- components/KebabMenu/KebabMenu.tsx | 1 - .../{[folderId].tsx => [[...folderId]].tsx} | 26 ++-- pages/folder/index.tsx | 115 ------------------ 4 files changed, 17 insertions(+), 128 deletions(-) rename pages/folder/{[folderId].tsx => [[...folderId]].tsx} (89%) delete mode 100644 pages/folder/index.tsx diff --git a/components/FolderButtonContainer/FolderButtonContainer.tsx b/components/FolderButtonContainer/FolderButtonContainer.tsx index f7454e177..b53f04199 100644 --- a/components/FolderButtonContainer/FolderButtonContainer.tsx +++ b/components/FolderButtonContainer/FolderButtonContainer.tsx @@ -1,4 +1,4 @@ -import { Dispatch, SetStateAction, useEffect, useState } from 'react'; +import { Dispatch, SetStateAction, useState } from 'react'; import * as S from './FolderButtonContainer.styled'; import FolderButton from '../FolderButton/FolderButton'; import { useModal } from '../../contexts/ModalContext'; @@ -23,6 +23,7 @@ function FolderButtonContainer({ booleanArr[index] = 'select'; setLinkSelected(booleanArr); setTotalBtn(false); + console.log(booleanArr); }; const handleClickTotalButton = () => { diff --git a/components/KebabMenu/KebabMenu.tsx b/components/KebabMenu/KebabMenu.tsx index 9828c1f0f..99b1ac87b 100644 --- a/components/KebabMenu/KebabMenu.tsx +++ b/components/KebabMenu/KebabMenu.tsx @@ -41,7 +41,6 @@ function KebabMenu({ !kebabRef.current.contains(e.target as Node) ) { setKebabView(!kebabView); - console.log(e.target as Node); } } diff --git a/pages/folder/[folderId].tsx b/pages/folder/[[...folderId]].tsx similarity index 89% rename from pages/folder/[folderId].tsx rename to pages/folder/[[...folderId]].tsx index ecdb493a8..465854cda 100644 --- a/pages/folder/[folderId].tsx +++ b/pages/folder/[[...folderId]].tsx @@ -46,11 +46,13 @@ function Folder() { useEffect(() => { const observer = new IntersectionObserver(handleObserver); - if (!loading && obsRef.current) observer.observe(obsRef.current); + if (!loading && obsRef.current) { + observer.observe(obsRef.current); + } return () => { observer.disconnect(); }; - }, [loading]); + }, [loading, folderId]); useEffect(() => { for (let i = 0; i < link.length; i++) { @@ -63,14 +65,14 @@ function Folder() { } }, [link, folderId]); - if (wrongFolder) { + if (folderId && wrongFolder) { return 존재하지 않는 폴더입니다!; } return ( <> -
+
@@ -93,17 +95,19 @@ function Folder() { {searchKeyword && ( -

{searchKeyword}

으로 검색한 결과입니다. +

{searchKeyword}

로 검색한 결과입니다.
)} - {onSelect.name} - + {folderId ? onSelect.name : '전체'} + {folderId && ( + + )} {linkList.length > 0 ? ( diff --git a/pages/folder/index.tsx b/pages/folder/index.tsx deleted file mode 100644 index 9aba0f584..000000000 --- a/pages/folder/index.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import { useContext } from 'react'; -import { useEffect, useRef, useState } from 'react'; -import * as S from '../../styles/folder.styled'; -import SearchBar from '../../components/SearchBar/SearchBar'; -import ContentsContainer from '../../components/ContentsContainer'; -import Card from '../../components/Card/Card'; -import useGetFolder from '../../hooks/useGetFolder'; -import useGetFolderList from '../../hooks/useGetFolderList'; -import FolderButtonContainer from '../../components/FolderButtonContainer/FolderButtonContainer'; -import { useModal } from '../../contexts/ModalContext'; -import AddModal from '../../components/Modal/AddModal/AddModal'; -import ModalPortal from '../../Portal'; -import { UserContext } from '@/contexts/UserContext'; -import FolderModals from '@/components/FolderModalContainer/FolderModals'; - -function Folder() { - const id = useContext(UserContext); - const [onSelect, setOnSelect] = useState({ - id: '', - name: '', - }); - const [searchKeyword, setSearchKeyWord] = useState(''); - const [url, setUrl] = useState(''); - const [toggleInput, setToggleInput] = useState(true); - const { linkList, loading } = useGetFolder(id, searchKeyword, onSelect.id); - const { link } = useGetFolderList(id); - const { modalState, openModal } = useModal(); - const obsRef = useRef(null); - const inputRef = useRef(null); - - const handleObserver = (entries: IntersectionObserverEntry[]) => { - entries.forEach((entry) => { - if (entry.isIntersecting) { - setToggleInput(false); - return; - } else { - setToggleInput(true); - return; - } - }); - }; - - useEffect(() => { - const observer = new IntersectionObserver(handleObserver); - if (!loading && obsRef.current) observer.observe(obsRef.current); - return () => { - observer.disconnect(); - }; - }, [loading]); - - return ( - <> -
- - - - - - { - openModal('add'); - if (inputRef.current) { - setUrl(inputRef.current.value); - } - }} - > - 추가하기 - - - - - - - {searchKeyword && ( - -

{searchKeyword}

으로 검색한 결과입니다. -
- )} - - - {onSelect.name ? onSelect.name : '전체'} - {onSelect.name && ( - - )} - - - {linkList.length > 0 ? ( - linkList.map((item) => ( - - )) - ) : ( - 저장된 링크가 없습니다. - )} - - {modalState.add && inputRef.current && ( - - - - )} -
- - ); -} - -export default Folder; From a189e41bb9aeb0140554bb0f5ab9f2ba3da15423 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Thu, 23 May 2024 14:46:56 +0900 Subject: [PATCH 08/34] =?UTF-8?q?fix:=20card=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20Image=ED=83=9C=EA=B7=B8=EB=A1=9C=20=EC=B5=9C?= =?UTF-8?q?=EC=A0=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Card/Card.styled.ts | 19 +++++++++++++------ components/Card/Card.tsx | 14 ++++++++++---- next.config.js | 12 ++++++++++++ 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/components/Card/Card.styled.ts b/components/Card/Card.styled.ts index 25faf06e2..bdd942ced 100644 --- a/components/Card/Card.styled.ts +++ b/components/Card/Card.styled.ts @@ -16,15 +16,19 @@ export const EmptyImg = styled.div` } `; -export const ItemImg = styled.div<{ image: string }>` +export const ItemImg = styled.div` + position: relative; height: 100%; - background-image: url(${(props) => props.image}); + width: 100%; border-radius: 1.5rem 1.5rem 0 0; - background-size: cover; - background-position: center; + transition: 0.3s ease; + + img { + object-fit: cover; + } &:hover { - background-size: 150%; + width: 170%; } `; @@ -33,12 +37,14 @@ export const ItemCard = styled.div` height: 33.4rem; display: flex; flex-direction: column; + align-items: center; box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.08); border-radius: 1.5rem; text-decoration: none; color: #000; position: relative; font-size: 1.6rem; + overflow: hidden; &:hover { background-color: var(--Background); @@ -49,13 +55,14 @@ export const ItemCard = styled.div` } `; -export const StarIcon = styled.img` +export const StarIcon = styled.div` width: 3.4rem; height: 3rem; flex-shrink: 0; position: absolute; top: 1.5rem; right: 1.5rem; + z-index: 1; `; export const ItemInfo = styled.div` diff --git a/components/Card/Card.tsx b/components/Card/Card.tsx index b72486c5a..347260ad8 100644 --- a/components/Card/Card.tsx +++ b/components/Card/Card.tsx @@ -48,15 +48,21 @@ function Card({ { setLike(!like); e.preventDefault(); }} - /> + > + 별 이미지 + {image_source ? ( - + + 카드 이미지 + ) : ( 빈 이미지 diff --git a/next.config.js b/next.config.js index 59874acc9..16c70f3a6 100644 --- a/next.config.js +++ b/next.config.js @@ -7,4 +7,16 @@ module.exports = { experimental: { forceSwcTransforms: true, }, + images: { + remotePatterns: [ + { + protocol: 'http', + hostname: '**', + }, + { + protocol: 'https', + hostname: '**', + }, + ], + }, }; From 608648613e23af5148566827759445795acdf4e6 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Thu, 23 May 2024 15:31:12 +0900 Subject: [PATCH 09/34] =?UTF-8?q?fix:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=ED=83=9C=EA=B7=B8=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Nav/Nav.styled.ts | 9 +++------ components/Nav/Nav.tsx | 12 ++++++++++-- pages/folder/[[...folderId]].tsx | 5 ++++- pages/shared.tsx | 7 +++++-- styles/folder.styled.ts | 2 +- styles/shared.styled.ts | 5 ----- 6 files changed, 23 insertions(+), 17 deletions(-) diff --git a/components/Nav/Nav.styled.ts b/components/Nav/Nav.styled.ts index ab9c6794a..466f73f40 100644 --- a/components/Nav/Nav.styled.ts +++ b/components/Nav/Nav.styled.ts @@ -6,11 +6,6 @@ export const NavModal = styled.div` align-items: center; `; -export const NavLogo = styled.img` - width: 13.3rem; - height: 2.4rem; -`; - export const UserProfile = styled.div` position: relative; display: flex; @@ -24,10 +19,12 @@ export const ProfileBody = styled.div` gap: 0.8rem; `; -export const UserPicture = styled.img` +export const UserPicture = styled.div` + position: relative; width: 2.8rem; height: 2.8rem; border-radius: 1.4rem; + overflow: hidden; `; export const NavBar = styled.div` diff --git a/components/Nav/Nav.tsx b/components/Nav/Nav.tsx index 52cda6e14..189610b81 100644 --- a/components/Nav/Nav.tsx +++ b/components/Nav/Nav.tsx @@ -3,6 +3,7 @@ import * as S from './Nav.styled'; import { User } from '../../hooks/useGetUser'; import Link from 'next/link'; import { Dispatch, useState } from 'react'; +import Image from 'next/image'; function NavUser({ user, @@ -20,7 +21,9 @@ function NavUser({ return ( - + + userPicture +

setToggle(!toggle)}>{user.email}

{toggle && ( @@ -38,7 +41,12 @@ function Nav({ user }: { user: User }) { - + 네이게이션 로고 {user.id ? ( diff --git a/pages/folder/[[...folderId]].tsx b/pages/folder/[[...folderId]].tsx index 465854cda..b4f37c5c8 100644 --- a/pages/folder/[[...folderId]].tsx +++ b/pages/folder/[[...folderId]].tsx @@ -13,6 +13,7 @@ import ModalPortal from '../../Portal'; import { UserContext } from '@/contexts/UserContext'; import FolderModals from '@/components/FolderModalContainer/FolderModals'; import { useRouter } from 'next/router'; +import Image from 'next/image'; function Folder() { const id = useContext(UserContext); @@ -75,7 +76,9 @@ function Folder() {
- + + 링크 아이콘 + - {folderOwner.name} {folderInfo.name} diff --git a/styles/folder.styled.ts b/styles/folder.styled.ts index 135be3e29..1b1928752 100644 --- a/styles/folder.styled.ts +++ b/styles/folder.styled.ts @@ -39,7 +39,7 @@ export const AddLinkInput = styled.input` } `; -export const LinkIcon = styled.img` +export const LinkIcon = styled.div` width: 2rem; height: 2rem; position: absolute; diff --git a/styles/shared.styled.ts b/styles/shared.styled.ts index 0d5d860d2..336096efa 100644 --- a/styles/shared.styled.ts +++ b/styles/shared.styled.ts @@ -18,11 +18,6 @@ export const OwnerProfile = styled.div` padding: 2rem 0 6rem 0; `; -export const OwnerProfileImage = styled.img` - width: 6rem; - height: 6rem; -`; - export const OwnerName = styled.p` font-family: Pretendard; font-size: 1.6rem; From 48461bfc7bb19f004fec9863f630cb2fb86feb58 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Thu, 23 May 2024 21:58:02 +0900 Subject: [PATCH 10/34] =?UTF-8?q?fix:=20=EC=98=B5=EC=A0=80=EB=B2=84=20?= =?UTF-8?q?=EC=9D=B8=EC=8B=9D=20=EC=95=88=EB=90=98=EB=8A=94=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FolderButtonContainer.tsx | 7 +- .../Modal/AddFolderModal/AddFolderModal.tsx | 1 - components/Modal/EditModal/EditModal.tsx | 1 - pages/folder/[[...folderId]].tsx | 82 +++++++++---------- styles/folder.styled.ts | 2 - 5 files changed, 46 insertions(+), 47 deletions(-) diff --git a/components/FolderButtonContainer/FolderButtonContainer.tsx b/components/FolderButtonContainer/FolderButtonContainer.tsx index b53f04199..797c1db7d 100644 --- a/components/FolderButtonContainer/FolderButtonContainer.tsx +++ b/components/FolderButtonContainer/FolderButtonContainer.tsx @@ -1,4 +1,4 @@ -import { Dispatch, SetStateAction, useState } from 'react'; +import { Dispatch, SetStateAction, useEffect, useState } from 'react'; import * as S from './FolderButtonContainer.styled'; import FolderButton from '../FolderButton/FolderButton'; import { useModal } from '../../contexts/ModalContext'; @@ -23,7 +23,6 @@ function FolderButtonContainer({ booleanArr[index] = 'select'; setLinkSelected(booleanArr); setTotalBtn(false); - console.log(booleanArr); }; const handleClickTotalButton = () => { @@ -33,6 +32,10 @@ function FolderButtonContainer({ setTotalBtn(true); }; + useEffect(() => { + console.log(1); + }, []); + return ( diff --git a/components/Modal/AddFolderModal/AddFolderModal.tsx b/components/Modal/AddFolderModal/AddFolderModal.tsx index a8ad9c7c4..721d8fe75 100644 --- a/components/Modal/AddFolderModal/AddFolderModal.tsx +++ b/components/Modal/AddFolderModal/AddFolderModal.tsx @@ -39,7 +39,6 @@ function AddFolderModal({ }} render={({ field, fieldState: { error } }) => ( ( 존재하지 않는 폴더입니다!; - } - return ( <> +
-
- 링크 아이콘 + 링크 아이콘
- - - {searchKeyword && ( - -

{searchKeyword}

로 검색한 결과입니다. -
- )} - - - {folderId ? onSelect.name : '전체'} - {folderId && ( - + {folderId && wrongFolder ? ( + 존재하지 않는 폴더입니다! + ) : ( + + + {searchKeyword && ( + +

{searchKeyword}

로 검색한 결과입니다. +
)} -
- - {linkList.length > 0 ? ( - linkList.map((item) => ( - + + {folderId ? onSelect.name : '전체'} + {folderId && ( + - )) - ) : ( - 저장된 링크가 없습니다. + )} + + + {linkList.length > 0 ? ( + linkList.map((item) => ( + + )) + ) : ( + 저장된 링크가 없습니다. + )} + + {modalState.add && inputRef.current && ( + + + )} - - {modalState.add && inputRef.current && ( - - - - )} -
+ + )} ); } diff --git a/styles/folder.styled.ts b/styles/folder.styled.ts index 1b1928752..78d31270f 100644 --- a/styles/folder.styled.ts +++ b/styles/folder.styled.ts @@ -40,8 +40,6 @@ export const AddLinkInput = styled.input` `; export const LinkIcon = styled.div` - width: 2rem; - height: 2rem; position: absolute; left: 2rem; @media (max-width: 768px) { From 43f6c23f44036721039b28e1359e1eaf89b2f168 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Fri, 24 May 2024 00:04:57 +0900 Subject: [PATCH 11/34] =?UTF-8?q?fix:=20notfound=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20css=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Button/Button.styled.ts | 1 + components/Card/Card.styled.ts | 2 +- components/Card/Card.tsx | 94 ++++++++++++------------ components/KebabMenu/KebabMenu.styled.ts | 2 +- components/KebabMenu/KebabMenu.tsx | 3 - components/NotFound/NotFound.styled.ts | 16 ++++ components/NotFound/NotFound.tsx | 14 ++++ hooks/useGetFolderList.ts | 4 + pages/folder/[[...folderId]].tsx | 85 ++++++++++----------- styles/folder.styled.ts | 9 ++- 10 files changed, 135 insertions(+), 95 deletions(-) create mode 100644 components/NotFound/NotFound.styled.ts create mode 100644 components/NotFound/NotFound.tsx diff --git a/components/Button/Button.styled.ts b/components/Button/Button.styled.ts index f63a1270d..624dde3a5 100644 --- a/components/Button/Button.styled.ts +++ b/components/Button/Button.styled.ts @@ -25,6 +25,7 @@ export const Cta = styled.button` line-height: normal; width: ${({ size }) => buttonSize[size]}rem; position: relative; + white-space: nowrap; &:hover { opacity: 0.8; diff --git a/components/Card/Card.styled.ts b/components/Card/Card.styled.ts index bdd942ced..87a2b44ce 100644 --- a/components/Card/Card.styled.ts +++ b/components/Card/Card.styled.ts @@ -17,10 +17,10 @@ export const EmptyImg = styled.div` `; export const ItemImg = styled.div` + border-radius: 1.5rem 1.5rem 0 0; position: relative; height: 100%; width: 100%; - border-radius: 1.5rem 1.5rem 0 0; transition: 0.3s ease; img { diff --git a/components/Card/Card.tsx b/components/Card/Card.tsx index 347260ad8..de42661bf 100644 --- a/components/Card/Card.tsx +++ b/components/Card/Card.tsx @@ -45,59 +45,61 @@ function Card({ }, [item]); return ( - - - { - setLike(!like); - e.preventDefault(); - }} - > - 별 이미지 - - {image_source ? ( - - 카드 이미지 - - ) : ( - - 빈 이미지 - - )} - - {onSelect && onSelect.name && ( - + + + { + setLike(!like); + e.preventDefault(); + }} + > + 별 이미지 + + {image_source ? ( + + 카드 이미지 + + ) : ( + + 빈 이미지 + )} - {createdText} - - {description ? description : url} - - {fullDate} - - {kebabView && ( - - )} - + + {onSelect && onSelect.name && ( + + )} + {createdText} + + {description ? description : url} + + {fullDate} + + {kebabView && ( + + )} +
+ {modalState.deleteLink && ( )} - + ); } diff --git a/components/KebabMenu/KebabMenu.styled.ts b/components/KebabMenu/KebabMenu.styled.ts index b55778ef5..ac6e4d8a0 100644 --- a/components/KebabMenu/KebabMenu.styled.ts +++ b/components/KebabMenu/KebabMenu.styled.ts @@ -2,7 +2,7 @@ import styled from 'styled-components'; export const ModalBody = styled.div` position: absolute; - right: -5rem; + right: 0; bottom: 1rem; width: 10rem; box-shadow: 0px 2px 8px 0px rgba(51, 50, 54, 0.1); diff --git a/components/KebabMenu/KebabMenu.tsx b/components/KebabMenu/KebabMenu.tsx index 99b1ac87b..10e64173a 100644 --- a/components/KebabMenu/KebabMenu.tsx +++ b/components/KebabMenu/KebabMenu.tsx @@ -1,12 +1,9 @@ import React, { Dispatch, SetStateAction, useEffect, useRef } from 'react'; import { useModal } from '@/contexts/ModalContext'; import * as S from './KebabMenu.styled'; -import ModalPortal from '@/Portal'; -import DeleteLinkModal from '../Modal/DeleteLinkModal/DeleteLinkModal'; function KebabMenu({ url, - id, setUrl, setKebabView, kebabView, diff --git a/components/NotFound/NotFound.styled.ts b/components/NotFound/NotFound.styled.ts new file mode 100644 index 000000000..bb6508a99 --- /dev/null +++ b/components/NotFound/NotFound.styled.ts @@ -0,0 +1,16 @@ +import styled from 'styled-components'; + +export const Body = styled.div` + height: 70vh; + width: 100%; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + gap: 2rem; + + p { + font-size: 3rem; + font-weight: 600; + } +`; diff --git a/components/NotFound/NotFound.tsx b/components/NotFound/NotFound.tsx new file mode 100644 index 000000000..9d178044b --- /dev/null +++ b/components/NotFound/NotFound.tsx @@ -0,0 +1,14 @@ +import { Button } from '@/components/Button/Button'; +import * as S from './NotFound.styled'; +import Link from 'next/link'; + +function NotFound() { + return ( + +

존재하지 않는 폴더입니다!

+

다른 폴더를 선택해주세요!

+
+ ); +} + +export default NotFound; diff --git a/hooks/useGetFolderList.ts b/hooks/useGetFolderList.ts index 445716038..ae1e1f17b 100644 --- a/hooks/useGetFolderList.ts +++ b/hooks/useGetFolderList.ts @@ -18,19 +18,23 @@ export interface Folders extends Array {} function useGetFolderList(userId: string, folderId?: string) { const [link, setLink] = useState([]); + const [loading, setLoading] = useState(false); useEffect(() => { if (userId) { + setLoading(true); const loadFolderList = async () => { const links = await getFolder(userId); setLink(links.data); }; loadFolderList(); + setLoading(false); } }, [userId, folderId]); return { link, + loading, }; } export default useGetFolderList; diff --git a/pages/folder/[[...folderId]].tsx b/pages/folder/[[...folderId]].tsx index e54dd3d47..a565b9af6 100644 --- a/pages/folder/[[...folderId]].tsx +++ b/pages/folder/[[...folderId]].tsx @@ -14,6 +14,7 @@ import { UserContext } from '@/contexts/UserContext'; import FolderModals from '@/components/FolderModalContainer/FolderModals'; import { useRouter } from 'next/router'; import Image from 'next/image'; +import NotFound from '@/components/NotFound/NotFound'; function Folder() { const id = useContext(UserContext); @@ -90,48 +91,50 @@ function Folder() {
- {folderId && wrongFolder ? ( - 존재하지 않는 폴더입니다! - ) : ( - - - {searchKeyword && ( - -

{searchKeyword}

로 검색한 결과입니다. -
- )} - - - {folderId ? onSelect.name : '전체'} - {folderId && ( - - )} - - - {linkList.length > 0 ? ( - linkList.map((item) => ( - + + {searchKeyword && ( + +

{searchKeyword}

로 검색한 결과입니다. +
+ )} + + {folderId && wrongFolder && loading ? ( + + ) : ( + <> + +

{folderId ? onSelect.name : '전체'}

+ {folderId && ( + - )) - ) : ( - 저장된 링크가 없습니다. - )} -
- {modalState.add && inputRef.current && ( - - - - )} -
- )} + )} + + + {linkList.length > 0 ? ( + linkList.map((item) => ( + + )) + ) : ( + 저장된 링크가 없습니다. + )} + + + )} + {modalState.add && inputRef.current && ( + + + + )} + ); } diff --git a/styles/folder.styled.ts b/styles/folder.styled.ts index 78d31270f..c22080a83 100644 --- a/styles/folder.styled.ts +++ b/styles/folder.styled.ts @@ -114,11 +114,14 @@ export const FolderModalContainer = styled.div` width: 100%; display: flex; justify-content: space-between; - font-family: Pretendard; - font-weight: 600; - font-size: 2.4rem; margin: 2.4rem auto; + p { + font-family: Pretendard; + font-weight: 600; + font-size: 2.4rem; + } + @media (max-width: 768px) { flex-direction: column; justify-content: center; From c59d505dcb51c7dd523aef572aa09ad79cd3d18c Mon Sep 17 00:00:00 2001 From: sj0724 Date: Fri, 24 May 2024 10:45:39 +0900 Subject: [PATCH 12/34] =?UTF-8?q?fix:=20card=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EC=9D=B4=EB=AF=B8=EC=A7=80=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20css=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Card/Card.styled.ts | 72 +++++++++++++----------- components/Card/Card.tsx | 8 ++- components/KebabMenu/KebabMenu.styled.ts | 2 +- 3 files changed, 45 insertions(+), 37 deletions(-) diff --git a/components/Card/Card.styled.ts b/components/Card/Card.styled.ts index 87a2b44ce..c5f0f651f 100644 --- a/components/Card/Card.styled.ts +++ b/components/Card/Card.styled.ts @@ -1,5 +1,36 @@ import styled from 'styled-components'; +export const ItemCard = styled.div` + width: 34rem; + display: flex; + flex-direction: column; + align-items: center; + box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.08); + border-radius: 1.5rem; + text-decoration: none; + color: #000; + position: relative; + font-size: 1.6rem; + + &:hover { + background-color: var(--Background); + } + + @media (max-width: 768px) { + font-size: 1.4rem; + } +`; + +export const StarIcon = styled.div` + width: 3.4rem; + height: 3rem; + flex-shrink: 0; + position: absolute; + top: 1.5rem; + right: 1.5rem; + z-index: 1; +`; + export const EmptyImg = styled.div` height: 100%; background-color: var(--EmptyArea); @@ -17,12 +48,10 @@ export const EmptyImg = styled.div` `; export const ItemImg = styled.div` - border-radius: 1.5rem 1.5rem 0 0; position: relative; - height: 100%; - width: 100%; transition: 0.3s ease; - + width: 100%; + height: 100%; img { object-fit: cover; } @@ -32,37 +61,14 @@ export const ItemImg = styled.div` } `; -export const ItemCard = styled.div` - width: 34rem; - height: 33.4rem; +export const ImageArea = styled.div` + border-radius: 1.5rem 1.5rem 0 0; + height: 23.5rem; + width: 100%; + overflow: hidden; display: flex; flex-direction: column; align-items: center; - box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.08); - border-radius: 1.5rem; - text-decoration: none; - color: #000; - position: relative; - font-size: 1.6rem; - overflow: hidden; - - &:hover { - background-color: var(--Background); - } - - @media (max-width: 768px) { - font-size: 1.4rem; - } -`; - -export const StarIcon = styled.div` - width: 3.4rem; - height: 3rem; - flex-shrink: 0; - position: absolute; - top: 1.5rem; - right: 1.5rem; - z-index: 1; `; export const ItemInfo = styled.div` @@ -70,7 +76,7 @@ export const ItemInfo = styled.div` flex-direction: column; padding: 1.5rem 2rem; width: 100%; - height: 13.5rem; + height: 10.5rem; gap: 1rem; position: relative; `; diff --git a/components/Card/Card.tsx b/components/Card/Card.tsx index de42661bf..74aac27e9 100644 --- a/components/Card/Card.tsx +++ b/components/Card/Card.tsx @@ -61,9 +61,11 @@ function Card({ /> {image_source ? ( - - 카드 이미지 - + + + 카드 이미지 + + ) : ( 빈 이미지 diff --git a/components/KebabMenu/KebabMenu.styled.ts b/components/KebabMenu/KebabMenu.styled.ts index ac6e4d8a0..a788f65c2 100644 --- a/components/KebabMenu/KebabMenu.styled.ts +++ b/components/KebabMenu/KebabMenu.styled.ts @@ -2,7 +2,7 @@ import styled from 'styled-components'; export const ModalBody = styled.div` position: absolute; - right: 0; + right: -3rem; bottom: 1rem; width: 10rem; box-shadow: 0px 2px 8px 0px rgba(51, 50, 54, 0.1); From f7b0de1aa61c64f05f765601f863d0c33f5ed5ea Mon Sep 17 00:00:00 2001 From: sj0724 Date: Fri, 24 May 2024 11:08:28 +0900 Subject: [PATCH 13/34] =?UTF-8?q?feat:=20=EB=A7=81=ED=81=AC=20=EB=B3=B5?= =?UTF-8?q?=EC=82=AC=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 1 + @types/import-env.d.ts | 5 +++++ .../FolderModalContainer/FolderModals.tsx | 2 +- components/Modal/BaseModal/BaseModal.tsx | 2 +- .../Modal/ShareModal/ShareModal.styled.ts | 1 + components/Modal/ShareModal/ShareModal.tsx | 19 +++++++++++++++++-- 6 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 .env create mode 100644 @types/import-env.d.ts diff --git a/.env b/.env new file mode 100644 index 000000000..1a5e1f492 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +NEXT_PUBLIC_BASE_URL = http://localhost:3000 \ No newline at end of file diff --git a/@types/import-env.d.ts b/@types/import-env.d.ts new file mode 100644 index 000000000..57671709a --- /dev/null +++ b/@types/import-env.d.ts @@ -0,0 +1,5 @@ +declare namespace NodeJS { + interface ProcessEnv { + NEXT_PUBLIC_BASE_URL: string; + } +} diff --git a/components/FolderModalContainer/FolderModals.tsx b/components/FolderModalContainer/FolderModals.tsx index 4c6d0462f..6b7d803c4 100644 --- a/components/FolderModalContainer/FolderModals.tsx +++ b/components/FolderModalContainer/FolderModals.tsx @@ -55,7 +55,7 @@ function FolderModals({ {modalState.share && ( - + )} {modalState.edit && ( diff --git a/components/Modal/BaseModal/BaseModal.tsx b/components/Modal/BaseModal/BaseModal.tsx index 1daac8811..6e9b1eb6f 100644 --- a/components/Modal/BaseModal/BaseModal.tsx +++ b/components/Modal/BaseModal/BaseModal.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import React from 'react'; import * as S from './BaseModal.styled'; import { useModal } from '@/contexts/ModalContext'; diff --git a/components/Modal/ShareModal/ShareModal.styled.ts b/components/Modal/ShareModal/ShareModal.styled.ts index 77b305b59..7ada308a9 100644 --- a/components/Modal/ShareModal/ShareModal.styled.ts +++ b/components/Modal/ShareModal/ShareModal.styled.ts @@ -35,6 +35,7 @@ export const ShareButtonBody = styled.div<{ $color: string }>` flex-direction: column; align-items: center; gap: 1rem; + cursor: pointer; p { color: var(--Linkbrary-gray100); diff --git a/components/Modal/ShareModal/ShareModal.tsx b/components/Modal/ShareModal/ShareModal.tsx index 9f0cfe8f5..6ee442b83 100644 --- a/components/Modal/ShareModal/ShareModal.tsx +++ b/components/Modal/ShareModal/ShareModal.tsx @@ -3,7 +3,19 @@ import * as S from './ShareModal.styled'; import BaseModal from '../BaseModal/BaseModal'; import Image from 'next/image'; -function ShareModal({ folderName }: { folderName: string }) { +function ShareModal({ + folderName, + folderId, +}: { + folderName: string; + folderId: string; +}) { + const shareLink = async () => { + await navigator.clipboard.writeText( + `${process.env.NEXT_PUBLIC_BASE_URL}/shared/${folderId}` + ); + }; + return ( @@ -33,7 +45,10 @@ function ShareModal({ folderName }: { folderName: string }) {

페이스북

- + shareLink()} + > 링크 아이콘 From c5e215400f1b183541d88f6c2a385b0ab48382dc Mon Sep 17 00:00:00 2001 From: sj0724 Date: Fri, 24 May 2024 11:21:15 +0900 Subject: [PATCH 14/34] =?UTF-8?q?feat:=20=ED=8F=B4=EB=8D=94=20=EA=B3=B5?= =?UTF-8?q?=EC=9C=A0=EC=8B=9C=20toast=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Modal/ShareModal/ShareModal.styled.ts | 5 ++++ components/Modal/ShareModal/ShareModal.tsx | 7 ++++- components/Toast/Toast.styled.ts | 23 ++++++++++++++++ components/Toast/Toast.tsx | 26 +++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 components/Toast/Toast.styled.ts create mode 100644 components/Toast/Toast.tsx diff --git a/components/Modal/ShareModal/ShareModal.styled.ts b/components/Modal/ShareModal/ShareModal.styled.ts index 7ada308a9..a24c7b833 100644 --- a/components/Modal/ShareModal/ShareModal.styled.ts +++ b/components/Modal/ShareModal/ShareModal.styled.ts @@ -57,3 +57,8 @@ export const ShareButtonBody = styled.div<{ $color: string }>` background-color: ${(props) => props.$color}; } `; + +export const Toast = styled.div` + position: absolute; + bottom: -4rem; +`; diff --git a/components/Modal/ShareModal/ShareModal.tsx b/components/Modal/ShareModal/ShareModal.tsx index 6ee442b83..8f7c57cba 100644 --- a/components/Modal/ShareModal/ShareModal.tsx +++ b/components/Modal/ShareModal/ShareModal.tsx @@ -1,7 +1,8 @@ -import React from 'react'; +import React, { useState } from 'react'; import * as S from './ShareModal.styled'; import BaseModal from '../BaseModal/BaseModal'; import Image from 'next/image'; +import Toast from '@/components/Toast/Toast'; function ShareModal({ folderName, @@ -10,10 +11,13 @@ function ShareModal({ folderName: string; folderId: string; }) { + const [toast, setToast] = useState(false); + const shareLink = async () => { await navigator.clipboard.writeText( `${process.env.NEXT_PUBLIC_BASE_URL}/shared/${folderId}` ); + setToast(true); }; return ( @@ -55,6 +59,7 @@ function ShareModal({

링크 복사

+ {toast && }
); } diff --git a/components/Toast/Toast.styled.ts b/components/Toast/Toast.styled.ts new file mode 100644 index 000000000..c9aa63ce6 --- /dev/null +++ b/components/Toast/Toast.styled.ts @@ -0,0 +1,23 @@ +import styled from 'styled-components'; + +export const ToastBody = styled.div` + position: absolute; + bottom: -6rem; + left: 50%; + transform: translate(-50%, 0); + padding: 1.2rem 2rem; + justify-content: center; + align-items: center; + border-radius: 0.8rem; + background: var(--Linkbrary-gray100); + box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25); + color: #fff; + p { + color: var(--Grayscale-10); + font-family: Pretendard; + font-size: 1.4rem; + font-style: normal; + font-weight: 500; + line-height: 18px; + } +`; diff --git a/components/Toast/Toast.tsx b/components/Toast/Toast.tsx new file mode 100644 index 000000000..fbba3f586 --- /dev/null +++ b/components/Toast/Toast.tsx @@ -0,0 +1,26 @@ +import { Dispatch, SetStateAction, useEffect } from 'react'; +import * as S from './Toast.styled'; + +interface ToastProps { + setToast: Dispatch>; + text: string; +} + +function Toast({ setToast, text }: ToastProps) { + useEffect(() => { + const timer = setTimeout(() => { + setToast(false); + }, 3000); + return () => { + clearTimeout(timer); + }; + }, [setToast]); + + return ( + +

{text}

+
+ ); +} + +export default Toast; From bbfe19b57d29e634557a42f7a8c926d7f6fa650a Mon Sep 17 00:00:00 2001 From: sj0724 Date: Fri, 24 May 2024 11:47:01 +0900 Subject: [PATCH 15/34] =?UTF-8?q?fix:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EA=B2=BD=EB=A1=9C=20404=EC=9D=BC=EB=95=8C=20=EB=A1=9C=EA=B3=A0?= =?UTF-8?q?=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Card/Card.styled.ts | 3 +-- components/Card/Card.tsx | 40 ++++++++++++++++++++++++---------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/components/Card/Card.styled.ts b/components/Card/Card.styled.ts index c5f0f651f..84466ef83 100644 --- a/components/Card/Card.styled.ts +++ b/components/Card/Card.styled.ts @@ -33,6 +33,7 @@ export const StarIcon = styled.div` export const EmptyImg = styled.div` height: 100%; + width: 100%; background-color: var(--EmptyArea); border-radius: 1.5rem 1.5rem 0 0; display: flex; @@ -42,8 +43,6 @@ export const EmptyImg = styled.div` img { opacity: 0.2; - width: 13.3rem; - height: 2.4rem; } `; diff --git a/components/Card/Card.tsx b/components/Card/Card.tsx index 74aac27e9..19fab8cc5 100644 --- a/components/Card/Card.tsx +++ b/components/Card/Card.tsx @@ -1,4 +1,10 @@ -import { Dispatch, SetStateAction, useEffect, useState } from 'react'; +import { + Dispatch, + SetStateAction, + SyntheticEvent, + useEffect, + useState, +} from 'react'; import { changeDate, calculateDate } from '../../util/util'; import * as S from './Card.styled'; import KebabMenu from '../KebabMenu/KebabMenu'; @@ -8,6 +14,7 @@ import Link from 'next/link'; import { useModal } from '@/contexts/ModalContext'; import ModalPortal from '@/Portal'; import DeleteLinkModal from '../Modal/DeleteLinkModal/DeleteLinkModal'; +import logo from '@/public/logo.svg'; function Card({ item, @@ -23,10 +30,10 @@ function Card({ }) { const [createdAt, setCreatedAt] = useState({ time: 0, result: '' }); const [fullDate, setFullDate] = useState(''); - const { image_source } = item; const [kebabView, setKebabView] = useState(false); const [like, setLike] = useState(false); - const { url, description, id } = item; + const { url, description, id, image_source } = item; + const [imageUrl, setImageUrl] = useState(image_source); const { modalState } = useModal(); const createdText = `${createdAt.time} ${createdAt.result} ago`; @@ -36,6 +43,10 @@ function Card({ e.preventDefault(); }; + const handleImgError = ( + e: React.SyntheticEvent + ) => {}; + useEffect(() => { const nowDate = new Date(); const createDate = new Date(item.created_at); @@ -60,17 +71,22 @@ function Card({ fill /> - {image_source ? ( - + + {imageUrl ? ( - 카드 이미지 + 카드 이미지 setImageUrl('')} + /> - - ) : ( - - 빈 이미지 - - )} + ) : ( + + 빈 이미지 + + )} + {onSelect && onSelect.name && ( Date: Fri, 24 May 2024 13:40:43 +0900 Subject: [PATCH 16/34] =?UTF-8?q?feat:=20=EC=BF=BC=EB=A6=AC=ED=8C=8C?= =?UTF-8?q?=EB=9D=BC=EB=AF=B8=ED=84=B0=EB=A1=9C=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=A1=B0=ED=9A=8C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + api/api.ts | 20 ++++ components/Card/Card.tsx | 14 +-- .../FolderButtonContainer.tsx | 4 - pages/folder/[[...folderId]].tsx | 2 +- pages/shared.tsx | 91 ----------------- pages/shared/[[...folderId]].tsx | 99 +++++++++++++++++++ styles/shared.styled.ts | 25 +++-- 8 files changed, 138 insertions(+), 118 deletions(-) delete mode 100644 pages/shared.tsx create mode 100644 pages/shared/[[...folderId]].tsx diff --git a/.gitignore b/.gitignore index 8f322f0d8..45c1abce8 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ yarn-error.log* # local env files .env*.local +.env # vercel .vercel diff --git a/api/api.ts b/api/api.ts index 769038f90..340e008ec 100644 --- a/api/api.ts +++ b/api/api.ts @@ -62,6 +62,16 @@ export async function getFolder(id: string) { } } +export async function getFolderData(folderId: string) { + try { + const { data } = await axios.get(`/folders/${folderId}`); + return data.data; + } catch (error) { + console.error('Error fetching folder:', error); + throw error; + } +} + export async function getFolderList(id: string, folderId: string) { if (folderId) { try { @@ -98,6 +108,16 @@ export async function getUser(accessToken: string) { } } +export async function getUserData(id: string) { + try { + const { data } = await axios.get(`/users/${id}`); + return data.data; + } catch (error) { + console.error('Error fetching user:', error); + throw error; + } +} + export async function postSignIn(id: string, password: string) { try { const { data } = await axios.post('/sign-in', { diff --git a/components/Card/Card.tsx b/components/Card/Card.tsx index 19fab8cc5..7cbfea6a1 100644 --- a/components/Card/Card.tsx +++ b/components/Card/Card.tsx @@ -1,10 +1,4 @@ -import { - Dispatch, - SetStateAction, - SyntheticEvent, - useEffect, - useState, -} from 'react'; +import { Dispatch, SetStateAction, useEffect, useState } from 'react'; import { changeDate, calculateDate } from '../../util/util'; import * as S from './Card.styled'; import KebabMenu from '../KebabMenu/KebabMenu'; @@ -22,7 +16,7 @@ function Card({ onSelect, }: { item: LinkData; - setUrl: Dispatch>; + setUrl?: Dispatch>; onSelect?: { id: string; name: string; @@ -43,10 +37,6 @@ function Card({ e.preventDefault(); }; - const handleImgError = ( - e: React.SyntheticEvent - ) => {}; - useEffect(() => { const nowDate = new Date(); const createDate = new Date(item.created_at); diff --git a/components/FolderButtonContainer/FolderButtonContainer.tsx b/components/FolderButtonContainer/FolderButtonContainer.tsx index 797c1db7d..f7454e177 100644 --- a/components/FolderButtonContainer/FolderButtonContainer.tsx +++ b/components/FolderButtonContainer/FolderButtonContainer.tsx @@ -32,10 +32,6 @@ function FolderButtonContainer({ setTotalBtn(true); }; - useEffect(() => { - console.log(1); - }, []); - return ( diff --git a/pages/folder/[[...folderId]].tsx b/pages/folder/[[...folderId]].tsx index a565b9af6..4cfb19225 100644 --- a/pages/folder/[[...folderId]].tsx +++ b/pages/folder/[[...folderId]].tsx @@ -99,7 +99,7 @@ function Folder() { )} - {folderId && wrongFolder && loading ? ( + {folderId && wrongFolder ? ( ) : ( <> diff --git a/pages/shared.tsx b/pages/shared.tsx deleted file mode 100644 index adc190103..000000000 --- a/pages/shared.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import { useEffect, useState } from 'react'; -import * as S from '../styles/shared.styled'; -import { getSampleFolder } from '../api/api'; -import Card from '../components/Card/Card'; -import SearchBar from '../components/SearchBar/SearchBar'; -import Image from 'next/image'; - -type FolderName = { - name: string; -}; - -type Owner = { - name: string; - profileImageSource: string; -}; - -type Link = { - id: number; - created_at: Date; - url: string; - title: string; - description: string; - image_source: string; -}; - -interface Links extends Array {} - -interface SampleFolder { - id: number; - name: FolderName; - owner: Owner; - links: Links; -} - -type Folder = { - folder: SampleFolder; -}; - -function Shared() { - const [folderInfo, setFolderInfo] = useState({ - name: '', - }); - const [linkList, setLinkList] = useState([]); - const [folderOwner, setFolderOwner] = useState({ - profileImageSource: '', - name: '', - }); - - const infoLoad = async () => { - const result: Folder = await getSampleFolder(); - const { folder } = result; - setFolderInfo(folder.name); - setFolderOwner(folder.owner); - setLinkList(folder.links); - }; - - useEffect(() => { - infoLoad(); - }, []); - - return ( - - - owner 이미지 - {folderOwner.name} - {folderInfo.name} - - - - ): void { - throw new Error('Function not implemented.'); - }} - /> - - {linkList.map((item) => ( - {}} /> - ))} - - - - ); -} - -export default Shared; diff --git a/pages/shared/[[...folderId]].tsx b/pages/shared/[[...folderId]].tsx new file mode 100644 index 000000000..d1dfac848 --- /dev/null +++ b/pages/shared/[[...folderId]].tsx @@ -0,0 +1,99 @@ +import { useContext, useEffect, useState } from 'react'; +import * as S from '../../styles/shared.styled'; +import { getFolderData, getSampleFolder, getUserData } from '../../api/api'; +import Card from '../../components/Card/Card'; +import SearchBar from '../../components/SearchBar/SearchBar'; +import Image from 'next/image'; +import { useRouter } from 'next/router'; +import useGetFolder from '@/hooks/useGetFolder'; +import ContentsContainer from '@/components/ContentsContainer'; + +type FolderName = { + name: string; +}; + +type Owner = { + name: string; + profileImageSource: string; +}; + +type Link = { + id: number; + created_at: Date; + url: string; + title: string; + description: string; + image_source: string; +}; + +interface Links extends Array {} + +interface SampleFolder { + id: number; + name: FolderName; + owner: Owner; + links: Links; +} + +type Folder = { + folder: SampleFolder; +}; + +function Shared() { + const [searchKeyword, setSearchKeyWord] = useState(''); + const [owner, setOwner] = useState({ + id: '', + created_at: new Date(), + name: '', + image_source: '', + email: '', + auth_id: '', + }); + const [folderName, setFolderName] = useState(''); + const router = useRouter(); + const folderId = router.query.folderId as string; + const userId = router.query['userId'] as string; + const { linkList, loading } = useGetFolder(userId, searchKeyword, folderId); + + useEffect(() => { + const loadOwnerData = async () => { + const user = await getUserData(userId); + if (user) { + setOwner(user[0]); + } + const folderName = await getFolderData(folderId); + if (folderName) { + setFolderName(folderName[0].name); + } + }; + loadOwnerData(); + }, [userId]); + + return ( + <> + + owner 이미지 + {owner.name} + {folderName} + + + + {searchKeyword &&

{searchKeyword}로 검색한 결과입니다.

} + + {linkList.length > 0 ? ( + linkList.map((item) => ) + ) : ( + 저장된 링크가 없습니다. + )} + +
+ + ); +} + +export default Shared; diff --git a/styles/shared.styled.ts b/styles/shared.styled.ts index 336096efa..7da32916f 100644 --- a/styles/shared.styled.ts +++ b/styles/shared.styled.ts @@ -1,13 +1,5 @@ import styled from 'styled-components'; -export const Shared = styled.div` - margin: 0 auto; - display: flex; - flex-direction: column; - align-items: center; - font-family: Pretendard; -`; - export const OwnerProfile = styled.div` background-color: var(--Background); width: 100%; @@ -40,10 +32,12 @@ export const FolderName = styled.p` `; export const SharedContent = styled.div` - margin: 0 auto; display: flex; - align-items: center; flex-direction: column; + justify-content: center; + align-items: center; + margin: 0 auto; + max-width: 106rem; @media (max-width: 1199px) { padding: 0 3.2rem; @@ -65,3 +59,14 @@ export const Container = styled.div` grid-template-columns: 1fr; } `; + +export const EmptyFolder = styled.div` + height: 50vh; + font-size: 1.6rem; + margin: 0 auto; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 8rem 0; +`; From 9f817c839af3e3a2c61ba6662df487dfa2f2d2ba Mon Sep 17 00:00:00 2001 From: sj0724 Date: Fri, 24 May 2024 15:14:19 +0900 Subject: [PATCH 17/34] =?UTF-8?q?feat:=20kakao=20=EA=B3=B5=EC=9C=A0?= =?UTF-8?q?=ED=95=98=EA=B8=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 3 +- components/Card/Card.tsx | 2 +- components/Modal/ShareModal/ShareModal.tsx | 17 ++++++--- pages/_app.tsx | 10 ++++++ pages/_document.tsx | 7 +++- pages/shared/[[...folderId]].tsx | 41 ++++------------------ 6 files changed, 38 insertions(+), 42 deletions(-) diff --git a/.env b/.env index 1a5e1f492..f2834e5b5 100644 --- a/.env +++ b/.env @@ -1 +1,2 @@ -NEXT_PUBLIC_BASE_URL = http://localhost:3000 \ No newline at end of file +NEXT_PUBLIC_BASE_URL = http://localhost:3000 +NEXT_PUBLIC_KAKAO_KEY= 9cffc5240e558f9948ff64d76927f0ed \ No newline at end of file diff --git a/components/Card/Card.tsx b/components/Card/Card.tsx index 7cbfea6a1..d3e7719fc 100644 --- a/components/Card/Card.tsx +++ b/components/Card/Card.tsx @@ -16,7 +16,7 @@ function Card({ onSelect, }: { item: LinkData; - setUrl?: Dispatch>; + setUrl: Dispatch>; onSelect?: { id: string; name: string; diff --git a/components/Modal/ShareModal/ShareModal.tsx b/components/Modal/ShareModal/ShareModal.tsx index 8f7c57cba..4d00e2942 100644 --- a/components/Modal/ShareModal/ShareModal.tsx +++ b/components/Modal/ShareModal/ShareModal.tsx @@ -1,8 +1,9 @@ -import React, { useState } from 'react'; +import React, { useContext, useState } from 'react'; import * as S from './ShareModal.styled'; import BaseModal from '../BaseModal/BaseModal'; import Image from 'next/image'; import Toast from '@/components/Toast/Toast'; +import { UserContext } from '@/contexts/UserContext'; function ShareModal({ folderName, @@ -11,15 +12,23 @@ function ShareModal({ folderName: string; folderId: string; }) { + const id = useContext(UserContext); const [toast, setToast] = useState(false); const shareLink = async () => { await navigator.clipboard.writeText( - `${process.env.NEXT_PUBLIC_BASE_URL}/shared/${folderId}` + `${process.env.NEXT_PUBLIC_BASE_URL}/shared/${folderId}?userId=${id}` ); setToast(true); }; + const shareKakao = () => { + const { Kakao } = window; + Kakao.Link.sendScrap({ + requestUrl: `${process.env.NEXT_PUBLIC_BASE_URL}/shared/${folderId}?userId=${id}`, + }); + }; + return ( @@ -27,7 +36,7 @@ function ShareModal({ {folderName} - + shareLink()} + onClick={shareLink} > 링크 아이콘 diff --git a/pages/_app.tsx b/pages/_app.tsx index 1e6a25727..8d55b5780 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -9,6 +9,12 @@ import { useEffect, useState } from 'react'; import { getUser } from '../api/api'; import { User } from '@/hooks/useGetUser'; +declare global { + interface Window { + Kakao: any; + } +} + export default function App({ Component, pageProps }: AppProps) { const [user, setUser] = useState({ id: '', @@ -30,6 +36,10 @@ export default function App({ Component, pageProps }: AppProps) { } }, []); + useEffect(() => { + window.Kakao.init(process.env.NEXT_PUBLIC_KAKAO_KEY); + }, []); + return ( <> diff --git a/pages/_document.tsx b/pages/_document.tsx index d03f88815..8fbd8fcb0 100644 --- a/pages/_document.tsx +++ b/pages/_document.tsx @@ -3,7 +3,12 @@ import { Html, Head, Main, NextScript } from 'next/document'; export default function Document() { return ( - + + +
diff --git a/pages/shared/[[...folderId]].tsx b/pages/shared/[[...folderId]].tsx index d1dfac848..3d2fca158 100644 --- a/pages/shared/[[...folderId]].tsx +++ b/pages/shared/[[...folderId]].tsx @@ -1,6 +1,6 @@ -import { useContext, useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; import * as S from '../../styles/shared.styled'; -import { getFolderData, getSampleFolder, getUserData } from '../../api/api'; +import { getFolderData, getUserData } from '../../api/api'; import Card from '../../components/Card/Card'; import SearchBar from '../../components/SearchBar/SearchBar'; import Image from 'next/image'; @@ -8,37 +8,6 @@ import { useRouter } from 'next/router'; import useGetFolder from '@/hooks/useGetFolder'; import ContentsContainer from '@/components/ContentsContainer'; -type FolderName = { - name: string; -}; - -type Owner = { - name: string; - profileImageSource: string; -}; - -type Link = { - id: number; - created_at: Date; - url: string; - title: string; - description: string; - image_source: string; -}; - -interface Links extends Array {} - -interface SampleFolder { - id: number; - name: FolderName; - owner: Owner; - links: Links; -} - -type Folder = { - folder: SampleFolder; -}; - function Shared() { const [searchKeyword, setSearchKeyWord] = useState(''); const [owner, setOwner] = useState({ @@ -67,7 +36,7 @@ function Shared() { } }; loadOwnerData(); - }, [userId]); + }, [folderId, userId]); return ( <> @@ -86,7 +55,9 @@ function Shared() { {searchKeyword &&

{searchKeyword}로 검색한 결과입니다.

} {linkList.length > 0 ? ( - linkList.map((item) => ) + linkList.map((item) => ( + {}} /> + )) ) : ( 저장된 링크가 없습니다. )} From 2d1c86c30b651fd40321dd82132f0769207bd5c1 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Fri, 24 May 2024 15:20:54 +0900 Subject: [PATCH 18/34] =?UTF-8?q?feat:=20facebook=20=EA=B3=B5=EC=9C=A0=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Modal/ShareModal/ShareModal.tsx | 31 +++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/components/Modal/ShareModal/ShareModal.tsx b/components/Modal/ShareModal/ShareModal.tsx index 4d00e2942..1e31959d5 100644 --- a/components/Modal/ShareModal/ShareModal.tsx +++ b/components/Modal/ShareModal/ShareModal.tsx @@ -24,11 +24,36 @@ function ShareModal({ const shareKakao = () => { const { Kakao } = window; - Kakao.Link.sendScrap({ - requestUrl: `${process.env.NEXT_PUBLIC_BASE_URL}/shared/${folderId}?userId=${id}`, + Kakao.Share.sendDefault({ + objectType: 'feed', + content: { + title: 'Linkbrary', + description: '나만의 폴더를 만들고 링크를 저장해보세요!', + imageUrl: '', + link: { + mobileWebUrl: `${process.env.NEXT_PUBLIC_BASE_URL}/shared/${folderId}?userId=${id}`, + }, + }, + buttons: [ + { + title: '링크 추가하러 가기', + link: { + mobileWebUrl: `${process.env.NEXT_PUBLIC_BASE_URL}/shared/${folderId}?userId=${id}`, + }, + }, + ], }); }; + const shareFacebook = () => { + const title = '페이스북 공유하기'; + window.open( + `https://www.facebook.com/sharer.php?u=${process.env.NEXT_PUBLIC_BASE_URL}/shared/${folderId}?userId=${id}`, + title, + 'toolbar=0,status=0,width=655,height=520' + ); + }; + return ( @@ -47,7 +72,7 @@ function ShareModal({

카카오톡

- + Date: Fri, 24 May 2024 15:43:44 +0900 Subject: [PATCH 19/34] =?UTF-8?q?fix:=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EC=82=AC=ED=95=AD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/api.ts | 2 -- components/Button/Button.styled.ts | 1 + hooks/useGetFolder.ts | 37 +++++++++++++++--------------- pages/signin.tsx | 5 +++- pages/signup.tsx | 5 +++- 5 files changed, 28 insertions(+), 22 deletions(-) diff --git a/api/api.ts b/api/api.ts index 340e008ec..caba6ae14 100644 --- a/api/api.ts +++ b/api/api.ts @@ -125,7 +125,6 @@ export async function postSignIn(id: string, password: string) { password: password, }); localStorage.setItem('token', data.data.accessToken); - window.location.href = '/'; return data; } catch (error) { console.error('Error fetching sign-in:', error); @@ -153,7 +152,6 @@ export async function postSignUp(id: string, password: string) { }); localStorage.setItem('token', data.data.accessToken); alert('회원가입이 완료되었습니다!'); - window.location.href = '/'; return data; } catch (error) { console.error('Error fetching sign-in:', error); diff --git a/components/Button/Button.styled.ts b/components/Button/Button.styled.ts index 624dde3a5..38e2a8252 100644 --- a/components/Button/Button.styled.ts +++ b/components/Button/Button.styled.ts @@ -33,5 +33,6 @@ export const Cta = styled.button` @media (max-width: 768px) { font-size: 1.4rem; + width: ${({ size }) => (size === 'lg' ? '25' : buttonSize[size])}rem; } `; diff --git a/hooks/useGetFolder.ts b/hooks/useGetFolder.ts index 00a26f5eb..37b2096ba 100644 --- a/hooks/useGetFolder.ts +++ b/hooks/useGetFolder.ts @@ -43,24 +43,25 @@ function useGetFolder(id: string, searchKeyword: string, folderId: string) { }; useEffect(() => { - if (id) { - try { - setLoading(true); - const loadFolder = async () => { - const list = await getFolderList(id, folderId); - if (searchKeyword) { - const searchList = search(list); - setLinkList(searchList); - } else { - setLinkList(list); - } - }; - loadFolder(); - setLoading(false); - } catch (error) { - console.error(error); - setLoading(false); - } + if (!id) { + return; + } + try { + setLoading(true); + const loadFolder = async () => { + const list = await getFolderList(id, folderId); + if (searchKeyword) { + const searchList = search(list); + setLinkList(searchList); + } else { + setLinkList(list); + } + }; + loadFolder(); + setLoading(false); + } catch (error) { + console.error(error); + setLoading(false); } }, [folderId, id, searchKeyword]); diff --git a/pages/signin.tsx b/pages/signin.tsx index f18e6da80..c4444ef7d 100644 --- a/pages/signin.tsx +++ b/pages/signin.tsx @@ -13,7 +13,10 @@ function SignIn() { const { handleSubmit, control } = useForm(); const formAction = async (data: any) => { - await postSignIn(data.id, data.password); + const result = await postSignIn(data.id, data.password); + if (result) { + window.location.href = '/'; + } }; const hiddenText = () => { diff --git a/pages/signup.tsx b/pages/signup.tsx index 809822779..e5c5b0afc 100644 --- a/pages/signup.tsx +++ b/pages/signup.tsx @@ -15,7 +15,10 @@ function SignUp() { const formAction = async (data: any) => { const result = await postCheckEmail(data.id); if (result) { - await postSignUp(data.id, data.password); + const signUp = await postSignUp(data.id, data.password); + if (signUp) { + window.location.href = '/'; + } } }; From 57c9514e2688cc48e15f240aafc0b53c6a8472d2 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Fri, 24 May 2024 22:58:59 +0900 Subject: [PATCH 20/34] =?UTF-8?q?fix:=20=EB=A9=94=EC=9D=B8=20=EC=84=B9?= =?UTF-8?q?=EC=85=98=20=EC=B9=B4=EB=93=9C=20css=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Button/Button.styled.ts | 2 +- .../MainSectionCard/MainSectionCard.styled.ts | 15 +++++++++++++-- components/MainSectionCard/MainSectionCard.tsx | 5 ++++- pages/index.tsx | 2 +- styles/index.styled.ts | 7 +++++-- 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/components/Button/Button.styled.ts b/components/Button/Button.styled.ts index 38e2a8252..96d9db5c6 100644 --- a/components/Button/Button.styled.ts +++ b/components/Button/Button.styled.ts @@ -33,6 +33,6 @@ export const Cta = styled.button` @media (max-width: 768px) { font-size: 1.4rem; - width: ${({ size }) => (size === 'lg' ? '25' : buttonSize[size])}rem; + padding: 1rem 1.6rem; } `; diff --git a/components/MainSectionCard/MainSectionCard.styled.ts b/components/MainSectionCard/MainSectionCard.styled.ts index 202cc3db1..eae36b05f 100644 --- a/components/MainSectionCard/MainSectionCard.styled.ts +++ b/components/MainSectionCard/MainSectionCard.styled.ts @@ -27,7 +27,6 @@ export const SectionCard = styled.div` 'description'; row-gap: 0.5rem; column-gap: 2.6rem; - justify-content: center; padding: 4rem 3.2rem; } `; @@ -61,6 +60,7 @@ export const Description = styled.p` margin: 0; grid-area: description; align-self: flex-start; + display: inline-block; @media (max-width: 768px) { font-size: 1.6rem; @@ -68,7 +68,18 @@ export const Description = styled.p` } `; -export const SectionImage = styled.img` +export const SectionImage = styled.div` width: 100%; + height: 45rem; grid-area: image; + position: relative; + + @media (max-width: 1199px) { + height: 31.5rem; + } + + @media (max-width: 768px) { + aspect-ratio: 1.2/1; + height: 100%; + } `; diff --git a/components/MainSectionCard/MainSectionCard.tsx b/components/MainSectionCard/MainSectionCard.tsx index a22d99321..a031fd695 100644 --- a/components/MainSectionCard/MainSectionCard.tsx +++ b/components/MainSectionCard/MainSectionCard.tsx @@ -1,5 +1,6 @@ import { useEffect, useState } from 'react'; import * as S from './MainSectionCard.styled'; +import Image from 'next/image'; interface SectionItem { title: string; @@ -15,7 +16,9 @@ function MainSectionCard({ item }: { item: SectionItem }) { {title} {description} - + + 색션 이미지 + ); } diff --git a/pages/index.tsx b/pages/index.tsx index 948877ab2..e9e2eb4bb 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -31,7 +31,7 @@ function Main() { - 헤더 이미지 + 헤더 이미지 diff --git a/styles/index.styled.ts b/styles/index.styled.ts index 324c8dc69..9d5ef9602 100644 --- a/styles/index.styled.ts +++ b/styles/index.styled.ts @@ -69,10 +69,13 @@ export const Header__image = styled.div` @media (max-width: 1199px) { width: 70rem; height: 34rem; + padding: 3rem 2.4rem 0; } @media (max-width: 768px) { - width: 100%; + height: 16rem; + width: 32.5rem; + padding: 1.3rem 1rem 0; } `; @@ -91,7 +94,7 @@ export const HeaderImage = styled.div` } @media (max-width: 768px) { - width: 100%; + height: 18rem; } `; From 832514158e1789a007e5586d5d2808cbbaccf1f5 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Sun, 26 May 2024 17:44:26 +0900 Subject: [PATCH 21/34] =?UTF-8?q?fix:=20=EB=A9=94=EC=9D=B8=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80,=20=EB=A1=9C=EA=B7=B8=EC=9D=B8,=20=ED=9A=8C?= =?UTF-8?q?=EC=9B=90=EA=B0=80=EC=9E=85=20=EB=B0=98=EC=9D=91=ED=98=95=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 --- components/Button/Button.styled.ts | 1 + components/Input/Input.styled.ts | 9 +++++++++ styles/index.styled.ts | 6 +++++- styles/signin.styled.ts | 10 ++++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/components/Button/Button.styled.ts b/components/Button/Button.styled.ts index 96d9db5c6..9ec33cfb5 100644 --- a/components/Button/Button.styled.ts +++ b/components/Button/Button.styled.ts @@ -34,5 +34,6 @@ export const Cta = styled.button` @media (max-width: 768px) { font-size: 1.4rem; padding: 1rem 1.6rem; + width: 100%; } `; diff --git a/components/Input/Input.styled.ts b/components/Input/Input.styled.ts index ceb6baed5..df0368a89 100644 --- a/components/Input/Input.styled.ts +++ b/components/Input/Input.styled.ts @@ -26,6 +26,15 @@ export const InputModal = styled.div<{ &:focus { border: 1px solid var(--Primary); } + + @media (max-width: 768px) { + width: 100%; + + input { + font-size: 1.4rem; + width: 100%; + } + } `; export const TextArea = styled.div` diff --git a/styles/index.styled.ts b/styles/index.styled.ts index 9d5ef9602..69c34233b 100644 --- a/styles/index.styled.ts +++ b/styles/index.styled.ts @@ -35,6 +35,11 @@ export const Header__contents = styled.div` @media (max-width: 768px) { gap: 1.5rem; + + a { + width: 100%; + max-width: 40rem; + } } `; @@ -133,7 +138,6 @@ export const Main__contents = styled.div` 'description'; row-gap: 0.5rem; column-gap: 2.6rem; - justify-content: center; padding: 4rem 3.2rem; } } diff --git a/styles/signin.styled.ts b/styles/signin.styled.ts index b871f8ec3..80fb45775 100644 --- a/styles/signin.styled.ts +++ b/styles/signin.styled.ts @@ -112,6 +112,11 @@ export const SnsLogin = styled.div` font-style: normal; font-weight: 400; line-height: normal; + + @media (max-width: 768px) { + width: 100%; + max-width: 40rem; + } `; export const SnsIcons = styled.div` @@ -154,4 +159,9 @@ export const SignForm = styled.form` display: flex; flex-direction: column; justify-content: flex-start; + + @media (max-width: 768px) { + width: 100%; + max-width: 40rem; + } `; From 5a88f7d3666f6df8fe406b335a4f9ed4358767ef Mon Sep 17 00:00:00 2001 From: sj0724 Date: Sun, 26 May 2024 18:04:19 +0900 Subject: [PATCH 22/34] =?UTF-8?q?fix:=20=ED=8F=B4=EB=8D=94=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=A0=91=EA=B7=BC=EC=8B=9C=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=EC=97=86=EC=9C=BC=EB=A9=B4=20=EB=A9=94=EC=9D=B8=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99,=20=EB=B2=84=ED=8A=BC=20=EB=B0=98=EC=9D=91?= =?UTF-8?q?=ED=98=95=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Button/Button.styled.ts | 2 +- pages/folder/[[...folderId]].tsx | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/components/Button/Button.styled.ts b/components/Button/Button.styled.ts index 9ec33cfb5..f0d73cb89 100644 --- a/components/Button/Button.styled.ts +++ b/components/Button/Button.styled.ts @@ -34,6 +34,6 @@ export const Cta = styled.button` @media (max-width: 768px) { font-size: 1.4rem; padding: 1rem 1.6rem; - width: 100%; + width: ${({ size }) => (size === 'lg' ? '100%' : `${buttonSize[size]}rem`)}; } `; diff --git a/pages/folder/[[...folderId]].tsx b/pages/folder/[[...folderId]].tsx index 4cfb19225..d90c55c06 100644 --- a/pages/folder/[[...folderId]].tsx +++ b/pages/folder/[[...folderId]].tsx @@ -47,6 +47,11 @@ function Folder() { }; useEffect(() => { + const access = localStorage.getItem('token'); + if (!access) { + router.replace('/'); + return; + } const observer = new IntersectionObserver(handleObserver); if (!loading && obsRef.current) { observer.observe(obsRef.current); @@ -54,7 +59,7 @@ function Folder() { return () => { observer.disconnect(); }; - }, [loading, folderId]); + }, [loading, folderId, router]); useEffect(() => { for (let i = 0; i < link.length; i++) { From 4611416700c6f4c5826bef18e607900b8ec90e38 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Sun, 26 May 2024 18:05:37 +0900 Subject: [PATCH 23/34] =?UTF-8?q?fix:=20=EC=BC=80=EB=B0=A5=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/KebabMenu/KebabMenu.styled.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/KebabMenu/KebabMenu.styled.ts b/components/KebabMenu/KebabMenu.styled.ts index a788f65c2..2b251c57d 100644 --- a/components/KebabMenu/KebabMenu.styled.ts +++ b/components/KebabMenu/KebabMenu.styled.ts @@ -2,7 +2,7 @@ import styled from 'styled-components'; export const ModalBody = styled.div` position: absolute; - right: -3rem; + right: -1rem; bottom: 1rem; width: 10rem; box-shadow: 0px 2px 8px 0px rgba(51, 50, 54, 0.1); From 74c431b1eab5d2991c2ce72c035e277e2b857e59 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Sun, 26 May 2024 18:35:36 +0900 Subject: [PATCH 24/34] =?UTF-8?q?fix:=20=EB=A7=81=ED=81=AC=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=EC=8B=9C=20=EB=8B=A4=EB=A5=B8=20=EB=A7=81=ED=81=AC=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=EB=90=98=EB=8A=94=20=EB=B2=84=EA=B7=B8=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 --- components/Card/Card.tsx | 16 ++++++---------- components/KebabMenu/KebabMenu.tsx | 6 ++++-- pages/folder/[[...folderId]].tsx | 8 ++++++++ pages/shared/[[...folderId]].tsx | 4 +--- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/components/Card/Card.tsx b/components/Card/Card.tsx index d3e7719fc..52a6b45a9 100644 --- a/components/Card/Card.tsx +++ b/components/Card/Card.tsx @@ -5,22 +5,21 @@ import KebabMenu from '../KebabMenu/KebabMenu'; import { LinkData } from '../../hooks/useGetFolder'; import Image from 'next/image'; import Link from 'next/link'; -import { useModal } from '@/contexts/ModalContext'; -import ModalPortal from '@/Portal'; -import DeleteLinkModal from '../Modal/DeleteLinkModal/DeleteLinkModal'; import logo from '@/public/logo.svg'; function Card({ item, setUrl, onSelect, + setLinkId, }: { item: LinkData; - setUrl: Dispatch>; + setUrl?: Dispatch>; onSelect?: { id: string; name: string; }; + setLinkId?: Dispatch>; }) { const [createdAt, setCreatedAt] = useState({ time: 0, result: '' }); const [fullDate, setFullDate] = useState(''); @@ -28,12 +27,14 @@ function Card({ const [like, setLike] = useState(false); const { url, description, id, image_source } = item; const [imageUrl, setImageUrl] = useState(image_source); - const { modalState } = useModal(); const createdText = `${createdAt.time} ${createdAt.result} ago`; const handleKebab = (e: React.MouseEvent) => { setKebabView(!kebabView); + if (setLinkId) { + setLinkId(id); + } e.preventDefault(); }; @@ -102,11 +103,6 @@ function Card({ )} - {modalState.deleteLink && ( - - - - )} ); } diff --git a/components/KebabMenu/KebabMenu.tsx b/components/KebabMenu/KebabMenu.tsx index 10e64173a..424f9b585 100644 --- a/components/KebabMenu/KebabMenu.tsx +++ b/components/KebabMenu/KebabMenu.tsx @@ -10,7 +10,7 @@ function KebabMenu({ }: { url: string; id: number; - setUrl: Dispatch>; + setUrl?: Dispatch>; setKebabView: Dispatch>; kebabView: boolean; }) { @@ -20,7 +20,9 @@ function KebabMenu({ const handleAddKebab = (e: React.MouseEvent) => { e.preventDefault(); openModal('add'); - setUrl(url); + if (setUrl) { + setUrl(url); + } }; const handleDeleteKebab = ( diff --git a/pages/folder/[[...folderId]].tsx b/pages/folder/[[...folderId]].tsx index d90c55c06..b11614a1d 100644 --- a/pages/folder/[[...folderId]].tsx +++ b/pages/folder/[[...folderId]].tsx @@ -15,6 +15,7 @@ import FolderModals from '@/components/FolderModalContainer/FolderModals'; import { useRouter } from 'next/router'; import Image from 'next/image'; import NotFound from '@/components/NotFound/NotFound'; +import DeleteLinkModal from '@/components/Modal/DeleteLinkModal/DeleteLinkModal'; function Folder() { const id = useContext(UserContext); @@ -26,6 +27,7 @@ function Folder() { const [url, setUrl] = useState(''); const [toggleInput, setToggleInput] = useState(true); const [wrongFolder, setWrongFolder] = useState(false); + const [linkId, setLinkId] = useState(0); const router = useRouter(); const folderId = router.query.folderId as string; const { linkList, loading } = useGetFolder(id, searchKeyword, folderId); @@ -126,6 +128,7 @@ function Folder() { key={item.id} setUrl={setUrl} onSelect={onSelect} + setLinkId={setLinkId} /> )) ) : ( @@ -139,6 +142,11 @@ function Folder() { )} + {modalState.deleteLink && ( + + + + )} ); diff --git a/pages/shared/[[...folderId]].tsx b/pages/shared/[[...folderId]].tsx index 3d2fca158..484abe47a 100644 --- a/pages/shared/[[...folderId]].tsx +++ b/pages/shared/[[...folderId]].tsx @@ -55,9 +55,7 @@ function Shared() { {searchKeyword &&

{searchKeyword}로 검색한 결과입니다.

} {linkList.length > 0 ? ( - linkList.map((item) => ( - {}} /> - )) + linkList.map((item) => ) ) : ( 저장된 링크가 없습니다. )} From 6042f20896853a1150b3013096383aa5fc4ff986 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Sun, 26 May 2024 18:43:41 +0900 Subject: [PATCH 25/34] =?UTF-8?q?feat:=20=ED=8F=B4=EB=8D=94=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EB=B3=80=EA=B2=BD=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/api.ts | 12 ++++++++++++ components/FolderModalContainer/FolderModals.tsx | 2 +- components/Modal/EditModal/EditModal.tsx | 10 +++++++--- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/api/api.ts b/api/api.ts index caba6ae14..01ef2ed28 100644 --- a/api/api.ts +++ b/api/api.ts @@ -205,3 +205,15 @@ export async function deleteLink(linkId: number) { console.error('Error fetching post folder:', error); } } + +export async function putFolder(folderId: string, name: string) { + try { + const { data } = await axios.put(`/folders/${folderId}`, { + name: name, + }); + return data; + } catch (error) { + alert('이름 수정에 실패했습니다!'); + console.error('Error fetching put folder:', error); + } +} diff --git a/components/FolderModalContainer/FolderModals.tsx b/components/FolderModalContainer/FolderModals.tsx index 6b7d803c4..d699c7b52 100644 --- a/components/FolderModalContainer/FolderModals.tsx +++ b/components/FolderModalContainer/FolderModals.tsx @@ -60,7 +60,7 @@ function FolderModals({ )} {modalState.edit && ( - + )} {modalState.delete && ( diff --git a/components/Modal/EditModal/EditModal.tsx b/components/Modal/EditModal/EditModal.tsx index f1ec2eb6f..f8558114c 100644 --- a/components/Modal/EditModal/EditModal.tsx +++ b/components/Modal/EditModal/EditModal.tsx @@ -3,12 +3,16 @@ import BaseModal from '../BaseModal/BaseModal'; import { Button } from '@/components/Button/Button'; import Input from '@/components/Input/Input'; import { Controller, useForm } from 'react-hook-form'; +import { putFolder } from '@/api/api'; +import { useRouter } from 'next/router'; -function EditModal() { +function EditModal({ folderId }: { folderId: string }) { const { handleSubmit, control } = useForm(); + const router = useRouter(); - const editFolder = (data: any) => { - console.log(data); + const editFolder = async (data: any) => { + await putFolder(folderId, data.edit); + router.reload(); }; return ( From 6196cc706b8f16f7cc39b93d588565fe6bbfc358 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Sun, 26 May 2024 19:33:31 +0900 Subject: [PATCH 26/34] =?UTF-8?q?fix:=20=ED=8C=8C=EC=9D=BC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=ED=99=95=EC=9D=B8=EC=9A=A9=20=EC=BB=A4=EB=B0=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 2 +- .vscode/settings.json | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 .vscode/settings.json diff --git a/.env b/.env index f2834e5b5..9ac249f3a 100644 --- a/.env +++ b/.env @@ -1,2 +1,2 @@ NEXT_PUBLIC_BASE_URL = http://localhost:3000 -NEXT_PUBLIC_KAKAO_KEY= 9cffc5240e558f9948ff64d76927f0ed \ No newline at end of file +NEXT_PUBLIC_KAKAO_KEY= 9cffc5240e558f9948ff64d76927f0ed diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..ef1860b8a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cSpell.words": ["Linkbrary"] +} From 70c346c53928947310b5f9041ac477fc3e5c96e1 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Sun, 26 May 2024 19:42:01 +0900 Subject: [PATCH 27/34] =?UTF-8?q?fix:=20env=ED=8C=8C=EC=9D=BC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 .env diff --git a/.env b/.env deleted file mode 100644 index 9ac249f3a..000000000 --- a/.env +++ /dev/null @@ -1,2 +0,0 @@ -NEXT_PUBLIC_BASE_URL = http://localhost:3000 -NEXT_PUBLIC_KAKAO_KEY= 9cffc5240e558f9948ff64d76927f0ed From bcc48ac71f6a50b2b27afa3adfbbeed5cad3f5a8 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Mon, 27 May 2024 09:50:31 +0900 Subject: [PATCH 28/34] =?UTF-8?q?feat:=20=EB=A1=9C=EB=94=A9=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Card/Card.tsx | 6 ++---- components/Loading/Loading.styled.ts | 31 ++++++++++++++++++++++++++++ components/Loading/Loading.tsx | 14 +++++++++++++ hooks/useGetFolder.ts | 4 ++-- hooks/useGetFolderList.ts | 15 +++++++++----- pages/folder/[[...folderId]].tsx | 4 +++- public/LoadingIcon.svg | 4 ++++ 7 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 components/Loading/Loading.styled.ts create mode 100644 components/Loading/Loading.tsx create mode 100644 public/LoadingIcon.svg diff --git a/components/Card/Card.tsx b/components/Card/Card.tsx index 52a6b45a9..9dff3197a 100644 --- a/components/Card/Card.tsx +++ b/components/Card/Card.tsx @@ -25,7 +25,7 @@ function Card({ const [fullDate, setFullDate] = useState(''); const [kebabView, setKebabView] = useState(false); const [like, setLike] = useState(false); - const { url, description, id, image_source } = item; + const { url, description, id, image_source, title } = item; const [imageUrl, setImageUrl] = useState(image_source); const createdText = `${createdAt.time} ${createdAt.result} ago`; @@ -87,9 +87,7 @@ function Card({ /> )} {createdText} - - {description ? description : url} - + {title ? title : description} {fullDate} {kebabView && ( diff --git a/components/Loading/Loading.styled.ts b/components/Loading/Loading.styled.ts new file mode 100644 index 000000000..49e768bd7 --- /dev/null +++ b/components/Loading/Loading.styled.ts @@ -0,0 +1,31 @@ +import styled, { keyframes } from 'styled-components'; + +const rotation = keyframes` + from{ + transform: rotate(0deg) + } + to{ + transform: rotate(360deg) + } +`; + +export const LoadingBody = styled.div` + position: fixed; + background-color: #fff; + opacity: 0.9; + left: 50%; + transform: translate(-50%, 0); + width: 100%; + height: 100vh; + margin: 0 auto; + z-index: 30; + display: flex; + justify-content: center; + align-items: center; +`; + +export const LoadingImage = styled.div` + animation: ${rotation} 2s linear infinite; + width: 100px; + height: 100px; +`; diff --git a/components/Loading/Loading.tsx b/components/Loading/Loading.tsx new file mode 100644 index 000000000..8685e1fa3 --- /dev/null +++ b/components/Loading/Loading.tsx @@ -0,0 +1,14 @@ +import Image from 'next/image'; +import * as S from './Loading.styled'; + +function Loading() { + return ( + + + 로딩 아이콘 + + + ); +} + +export default Loading; diff --git a/hooks/useGetFolder.ts b/hooks/useGetFolder.ts index 37b2096ba..07acdaa34 100644 --- a/hooks/useGetFolder.ts +++ b/hooks/useGetFolder.ts @@ -53,15 +53,15 @@ function useGetFolder(id: string, searchKeyword: string, folderId: string) { if (searchKeyword) { const searchList = search(list); setLinkList(searchList); + setLoading(false); } else { setLinkList(list); + setLoading(false); } }; loadFolder(); - setLoading(false); } catch (error) { console.error(error); - setLoading(false); } }, [folderId, id, searchKeyword]); diff --git a/hooks/useGetFolderList.ts b/hooks/useGetFolderList.ts index ae1e1f17b..a6e1ece18 100644 --- a/hooks/useGetFolderList.ts +++ b/hooks/useGetFolderList.ts @@ -18,23 +18,28 @@ export interface Folders extends Array {} function useGetFolderList(userId: string, folderId?: string) { const [link, setLink] = useState([]); - const [loading, setLoading] = useState(false); + const [linkLoading, setLinkLoading] = useState(false); useEffect(() => { - if (userId) { - setLoading(true); + if (!userId) { + return; + } + try { + setLinkLoading(true); const loadFolderList = async () => { const links = await getFolder(userId); setLink(links.data); + setLinkLoading(false); }; loadFolderList(); - setLoading(false); + } catch (error) { + console.error(); } }, [userId, folderId]); return { link, - loading, + linkLoading, }; } export default useGetFolderList; diff --git a/pages/folder/[[...folderId]].tsx b/pages/folder/[[...folderId]].tsx index b11614a1d..c748094bb 100644 --- a/pages/folder/[[...folderId]].tsx +++ b/pages/folder/[[...folderId]].tsx @@ -16,6 +16,7 @@ import { useRouter } from 'next/router'; import Image from 'next/image'; import NotFound from '@/components/NotFound/NotFound'; import DeleteLinkModal from '@/components/Modal/DeleteLinkModal/DeleteLinkModal'; +import Loading from '@/components/Loading/Loading'; function Folder() { const id = useContext(UserContext); @@ -31,7 +32,7 @@ function Folder() { const router = useRouter(); const folderId = router.query.folderId as string; const { linkList, loading } = useGetFolder(id, searchKeyword, folderId); - const { link } = useGetFolderList(id, folderId); + const { link, linkLoading } = useGetFolderList(id, folderId); const { modalState, openModal } = useModal(); const obsRef = useRef(null); const inputRef = useRef(null); @@ -76,6 +77,7 @@ function Folder() { return ( <> + {linkLoading || loading ? : null}
diff --git a/public/LoadingIcon.svg b/public/LoadingIcon.svg new file mode 100644 index 000000000..99f3ea3c2 --- /dev/null +++ b/public/LoadingIcon.svg @@ -0,0 +1,4 @@ + + + + From df5ea653a80cfdb312701311089e5c660032548a Mon Sep 17 00:00:00 2001 From: sj0724 Date: Mon, 27 May 2024 10:02:40 +0900 Subject: [PATCH 29/34] =?UTF-8?q?fix:=20=EA=B2=80=EC=83=89=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=98=B5=EC=85=94=EB=84=90=20=EC=B2=B4=EC=9D=B4?= =?UTF-8?q?=EB=8B=9D=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hooks/useGetFolder.ts | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/hooks/useGetFolder.ts b/hooks/useGetFolder.ts index 07acdaa34..ed814adab 100644 --- a/hooks/useGetFolder.ts +++ b/hooks/useGetFolder.ts @@ -19,27 +19,15 @@ function useGetFolder(id: string, searchKeyword: string, folderId: string) { const [loading, setLoading] = useState(false); const search = (list: Links) => { - let arr: Links = []; - for (let i = 0; i < list.length; i++) { - if (list[i].title) { - if (list[i].title.includes(searchKeyword)) { - arr = [...arr, list[i]]; - continue; - } - } - if (list[i].description) { - if (list[i].description.includes(searchKeyword)) { - arr = [...arr, list[i]]; - continue; - } - } - if (list[i].url) { - if (list[i].url.includes(searchKeyword)) { - arr = [...arr, list[i]]; - } - } + if (list) { + const searchLinks = list.filter( + (link) => + link.url?.includes(searchKeyword) || + link.title?.includes(searchKeyword) || + link.description?.includes(searchKeyword) + ); + setLinkList(searchLinks); } - return arr; }; useEffect(() => { @@ -51,8 +39,7 @@ function useGetFolder(id: string, searchKeyword: string, folderId: string) { const loadFolder = async () => { const list = await getFolderList(id, folderId); if (searchKeyword) { - const searchList = search(list); - setLinkList(searchList); + search(list); setLoading(false); } else { setLinkList(list); From 64b738612b95597251ff550d61c27e2cedb0acfb Mon Sep 17 00:00:00 2001 From: sj0724 Date: Tue, 28 May 2024 13:22:47 +0900 Subject: [PATCH 30/34] =?UTF-8?q?fix:=20shared=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EB=9D=BC=EC=9A=B0=ED=84=B0=20=EC=BF=BC=EB=A6=AC?= =?UTF-8?q?=EC=97=90=EC=84=9C=20userid=EA=B0=92=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Modal/ShareModal/ShareModal.tsx | 2 +- pages/shared/[[...folderId]].tsx | 34 ++++++++++++++-------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/components/Modal/ShareModal/ShareModal.tsx b/components/Modal/ShareModal/ShareModal.tsx index 1e31959d5..d0ff179c8 100644 --- a/components/Modal/ShareModal/ShareModal.tsx +++ b/components/Modal/ShareModal/ShareModal.tsx @@ -17,7 +17,7 @@ function ShareModal({ const shareLink = async () => { await navigator.clipboard.writeText( - `${process.env.NEXT_PUBLIC_BASE_URL}/shared/${folderId}?userId=${id}` + `${process.env.NEXT_PUBLIC_BASE_URL}/shared/${folderId}` ); setToast(true); }; diff --git a/pages/shared/[[...folderId]].tsx b/pages/shared/[[...folderId]].tsx index 484abe47a..42e6364d6 100644 --- a/pages/shared/[[...folderId]].tsx +++ b/pages/shared/[[...folderId]].tsx @@ -21,21 +21,31 @@ function Shared() { const [folderName, setFolderName] = useState(''); const router = useRouter(); const folderId = router.query.folderId as string; - const userId = router.query['userId'] as string; + const [userId, setUserId] = useState(''); const { linkList, loading } = useGetFolder(userId, searchKeyword, folderId); + const loadOwnerFolderData = async () => { + const folder = await getFolderData(folderId); + if (folder) { + setFolderName(folder[0].name); + setUserId(folder[0].user_id); + } + }; + + const loadOwnerData = async () => { + const user = await getUserData(userId); + if (user) { + setOwner(user[0]); + } + }; + useEffect(() => { - const loadOwnerData = async () => { - const user = await getUserData(userId); - if (user) { - setOwner(user[0]); - } - const folderName = await getFolderData(folderId); - if (folderName) { - setFolderName(folderName[0].name); - } - }; - loadOwnerData(); + if (folderId) { + loadOwnerFolderData(); + } + if (userId) { + loadOwnerData(); + } }, [folderId, userId]); return ( From 12719d7bb85b14936b4cc0f45d1f2c15cd656021 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Tue, 28 May 2024 13:33:41 +0900 Subject: [PATCH 31/34] =?UTF-8?q?fix:=20card=20css=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/ContentsContainer.tsx | 1 - styles/reset.css | 4 ---- 2 files changed, 5 deletions(-) diff --git a/components/ContentsContainer.tsx b/components/ContentsContainer.tsx index fd8b487b1..609c5b6a8 100644 --- a/components/ContentsContainer.tsx +++ b/components/ContentsContainer.tsx @@ -2,7 +2,6 @@ import { ReactNode } from 'react'; import styled from 'styled-components'; const Container = styled.div<{ $empty: number }>` - min-height: 40rem; gap: 2rem; display: grid; grid-template-columns: ${(props) => diff --git a/styles/reset.css b/styles/reset.css index 5d0ebf24b..b6a7e2f42 100644 --- a/styles/reset.css +++ b/styles/reset.css @@ -143,7 +143,3 @@ button { a { text-decoration: none; } - -::-webkit-scrollbar { - display: none; -} From 1015c206bea167d97cfd5a7625bbbe10d7093de0 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Tue, 28 May 2024 15:01:31 +0900 Subject: [PATCH 32/34] =?UTF-8?q?fix:=20=ED=8F=B4=EB=8D=94=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80,=20=EB=A7=81=ED=81=AC=20=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=EA=B8=80=EC=9E=90=EC=88=98=20=EC=A0=9C=ED=95=9C=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Modal/AddFolderModal/AddFolderModal.tsx | 1 + components/SearchBar/SearchBar.tsx | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/components/Modal/AddFolderModal/AddFolderModal.tsx b/components/Modal/AddFolderModal/AddFolderModal.tsx index 721d8fe75..f92ad9d82 100644 --- a/components/Modal/AddFolderModal/AddFolderModal.tsx +++ b/components/Modal/AddFolderModal/AddFolderModal.tsx @@ -36,6 +36,7 @@ function AddFolderModal({ control={control} rules={{ required: '내용을 입력해주세요!', + maxLength: { value: 10, message: '10자 이하로 입력해주세요!' }, }} render={({ field, fieldState: { error } }) => ( ) => { e.preventDefault(); + if (text.length >= 30) { + alert('30자 이하로 검색가능합니다!'); + return; + } setSearchKeyWord(text); }; From 297e4239a9334f66567e24449b9c8e731016699c Mon Sep 17 00:00:00 2001 From: sj0724 Date: Tue, 28 May 2024 19:56:11 +0900 Subject: [PATCH 33/34] =?UTF-8?q?fix:=20prerender=EC=8B=9C=EC=A0=90?= =?UTF-8?q?=EC=97=90=EC=84=9C=20css=EB=8F=84=20=ED=8F=AC=ED=95=A8=ED=95=B4?= =?UTF-8?q?=EC=84=9C=20=EB=A0=8C=EB=8D=94=EB=A7=81=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/api.ts | 6 +--- pages/_document.tsx | 67 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 52 insertions(+), 21 deletions(-) diff --git a/api/api.ts b/api/api.ts index 01ef2ed28..66e7d4f7b 100644 --- a/api/api.ts +++ b/api/api.ts @@ -173,11 +173,7 @@ export async function postFolder(name: string) { export async function deleteFolder(folderId: string) { try { const token = localStorage.getItem('token'); - const { data } = await axios.delete(`/folders/${folderId}`, { - headers: { - Authorization: token, - }, - }); + const { data } = await axios.delete(`/folders/${folderId}`); return data; } catch (error) { console.error('Error fetching post folder:', error); diff --git a/pages/_document.tsx b/pages/_document.tsx index 8fbd8fcb0..0c1f3d53f 100644 --- a/pages/_document.tsx +++ b/pages/_document.tsx @@ -1,19 +1,54 @@ import { Html, Head, Main, NextScript } from 'next/document'; +import Document, { DocumentContext } from 'next/document'; +import { ServerStyleSheet } from 'styled-components'; -export default function Document() { - return ( - - - - - -
- - - - - ); +class MyDocument extends Document { + static async getInitialProps(ctx: DocumentContext) { + const sheet = new ServerStyleSheet(); + const originalRenderPage = ctx.renderPage; + + try { + ctx.renderPage = () => + originalRenderPage({ + enhanceApp: (App) => (props) => + sheet.collectStyles(), + }); + + const initialProps = await Document.getInitialProps(ctx); + + return { + ...initialProps, + styles: [ + <> + {initialProps.styles} + {sheet.getStyleElement()} + , + ], + }; + } catch (error) { + throw error; + } finally { + sheet.seal(); + } + } + + render() { + return ( + + + + + +
+ + + + + ); + } } + +export default MyDocument; From e86564440dd5826837649be148bb519f7dbb9774 Mon Sep 17 00:00:00 2001 From: sj0724 Date: Tue, 28 May 2024 20:43:17 +0900 Subject: [PATCH 34/34] =?UTF-8?q?fix:=20=EB=A0=88=EC=9D=B4=EC=95=84?= =?UTF-8?q?=EC=9B=83=20=EC=89=AC=ED=94=84=ED=8A=B8=20=EB=B0=A9=EC=A7=80=20?= =?UTF-8?q?=EB=B0=8F=20=EB=A9=94=EC=9D=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20css=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Nav/Nav.styled.ts | 1 + pages/shared/[[...folderId]].tsx | 37 ++++++++++++++++++-------------- styles/index.styled.ts | 21 +++++++++--------- styles/shared.styled.ts | 19 ++++++++++++++++ 4 files changed, 52 insertions(+), 26 deletions(-) diff --git a/components/Nav/Nav.styled.ts b/components/Nav/Nav.styled.ts index 466f73f40..c56cafc29 100644 --- a/components/Nav/Nav.styled.ts +++ b/components/Nav/Nav.styled.ts @@ -4,6 +4,7 @@ export const NavModal = styled.div` display: flex; justify-content: space-between; align-items: center; + height: 3rem; `; export const UserProfile = styled.div` diff --git a/pages/shared/[[...folderId]].tsx b/pages/shared/[[...folderId]].tsx index 42e6364d6..1f02d450b 100644 --- a/pages/shared/[[...folderId]].tsx +++ b/pages/shared/[[...folderId]].tsx @@ -7,6 +7,7 @@ import Image from 'next/image'; import { useRouter } from 'next/router'; import useGetFolder from '@/hooks/useGetFolder'; import ContentsContainer from '@/components/ContentsContainer'; +import Loading from '@/components/Loading/Loading'; function Shared() { const [searchKeyword, setSearchKeyWord] = useState(''); @@ -24,22 +25,21 @@ function Shared() { const [userId, setUserId] = useState(''); const { linkList, loading } = useGetFolder(userId, searchKeyword, folderId); - const loadOwnerFolderData = async () => { - const folder = await getFolderData(folderId); - if (folder) { - setFolderName(folder[0].name); - setUserId(folder[0].user_id); - } - }; - - const loadOwnerData = async () => { - const user = await getUserData(userId); - if (user) { - setOwner(user[0]); - } - }; - useEffect(() => { + const loadOwnerFolderData = async () => { + const folder = await getFolderData(folderId); + if (folder) { + setFolderName(folder[0].name); + setUserId(folder[0].user_id); + } + }; + + const loadOwnerData = async () => { + const user = await getUserData(userId); + if (user) { + setOwner(user[0]); + } + }; if (folderId) { loadOwnerFolderData(); } @@ -50,6 +50,7 @@ function Shared() { return ( <> + {loading && } - {searchKeyword &&

{searchKeyword}로 검색한 결과입니다.

} + {searchKeyword && ( + +

{searchKeyword}

로 검색한 결과입니다. +
+ )} {linkList.length > 0 ? ( linkList.map((item) => ) diff --git a/styles/index.styled.ts b/styles/index.styled.ts index 69c34233b..fa37d04f8 100644 --- a/styles/index.styled.ts +++ b/styles/index.styled.ts @@ -34,7 +34,7 @@ export const Header__contents = styled.div` width: 100%; @media (max-width: 768px) { - gap: 1.5rem; + gap: 2.4rem; a { width: 100%; @@ -68,25 +68,25 @@ export const Slogan_gradient = styled.span` export const Header__image = styled.div` width: 120rem; height: 59rem; - padding: 5rem 4rem 0; + padding: 5rem 4.1rem 0; overflow: hidden; @media (max-width: 1199px) { - width: 70rem; - height: 34rem; - padding: 3rem 2.4rem 0; + width: 69.8rem; + height: 34.3rem; + padding: 2.9rem 2.4rem 0; } @media (max-width: 768px) { - height: 16rem; - width: 32.5rem; - padding: 1.3rem 1rem 0; + width: 100%; + height: 100%; + aspect-ratio: 2 / 1; } `; export const HeaderImage = styled.div` position: relative; - height: 66rem; + height: 65.9rem; width: 100%; img { @@ -99,7 +99,8 @@ export const HeaderImage = styled.div` } @media (max-width: 768px) { - height: 18rem; + aspect-ratio: 1.7 / 1; + height: auto; } `; diff --git a/styles/shared.styled.ts b/styles/shared.styled.ts index 7da32916f..8af73435f 100644 --- a/styles/shared.styled.ts +++ b/styles/shared.styled.ts @@ -17,6 +17,7 @@ export const OwnerName = styled.p` font-weight: 400; line-height: 2.4rem; margin-top: 1.2rem; + height: 2.4rem; `; export const FolderName = styled.p` @@ -29,6 +30,7 @@ export const FolderName = styled.p` font-weight: 600; line-height: normal; margin-top: 2rem; + height: 5.5rem; `; export const SharedContent = styled.div` @@ -70,3 +72,20 @@ export const EmptyFolder = styled.div` align-items: center; padding: 8rem 0; `; + +export const SearchResult = styled.div` + display: flex; + width: 100%; + margin-bottom: 4rem; + color: var(--Linkbrary-gray60); + font-family: Pretendard; + font-size: 3.2rem; + font-style: normal; + font-weight: 600; + line-height: normal; + letter-spacing: -0.2px; + + p { + color: var(--Linkbrary-gray100); + } +`;