diff --git a/weatherfit_refactoring/package-lock.json b/weatherfit_refactoring/package-lock.json
index 35fd8b7..9a2c523 100644
--- a/weatherfit_refactoring/package-lock.json
+++ b/weatherfit_refactoring/package-lock.json
@@ -8,8 +8,11 @@
"name": "weatherfit_refectoring",
"version": "0.1.0",
"dependencies": {
+ "@types/jsonwebtoken": "^9.0.6",
"axios": "^1.6.7",
+ "dompurify": "^3.0.11",
"js-cookie": "^3.0.5",
+ "jsonwebtoken": "^9.0.2",
"next": "14.0.4",
"react": "^18",
"react-dom": "^18",
@@ -19,6 +22,7 @@
"zustand": "^4.4.7"
},
"devDependencies": {
+ "@types/dompurify": "^3.0.5",
"@types/js-cookie": "^3.0.6",
"@types/node": "^20",
"@types/react": "^18",
@@ -455,6 +459,15 @@
"tslib": "^2.4.0"
}
},
+ "node_modules/@types/dompurify": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz",
+ "integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==",
+ "dev": true,
+ "dependencies": {
+ "@types/trusted-types": "*"
+ }
+ },
"node_modules/@types/js-cookie": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.6.tgz",
@@ -467,11 +480,18 @@
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
"dev": true
},
+ "node_modules/@types/jsonwebtoken": {
+ "version": "9.0.6",
+ "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.6.tgz",
+ "integrity": "sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/node": {
"version": "20.10.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz",
"integrity": "sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==",
- "dev": true,
"dependencies": {
"undici-types": "~5.26.4"
}
@@ -508,6 +528,12 @@
"integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==",
"devOptional": true
},
+ "node_modules/@types/trusted-types": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+ "dev": true
+ },
"node_modules/@typescript-eslint/parser": {
"version": "6.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.17.0.tgz",
@@ -1038,6 +1064,11 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/buffer-equal-constant-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
+ },
"node_modules/busboy": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
@@ -1349,12 +1380,25 @@
"node": ">=6.0.0"
}
},
+ "node_modules/dompurify": {
+ "version": "3.0.11",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.11.tgz",
+ "integrity": "sha512-Fan4uMuyB26gFV3ovPoEoQbxRRPfTu3CvImyZnhGq5fsIEO+gEFLp45ISFt+kQBWsK5ulDdT0oV28jS1UrwQLg=="
+ },
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"dev": true
},
+ "node_modules/ecdsa-sig-formatter": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
"node_modules/electron-to-chromium": {
"version": "1.4.620",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.620.tgz",
@@ -2913,6 +2957,27 @@
"json5": "lib/cli.js"
}
},
+ "node_modules/jsonwebtoken": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
+ "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
+ "dependencies": {
+ "jws": "^3.2.2",
+ "lodash.includes": "^4.3.0",
+ "lodash.isboolean": "^3.0.3",
+ "lodash.isinteger": "^4.0.4",
+ "lodash.isnumber": "^3.0.3",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.isstring": "^4.0.1",
+ "lodash.once": "^4.0.0",
+ "ms": "^2.1.1",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">=12",
+ "npm": ">=6"
+ }
+ },
"node_modules/jsx-ast-utils": {
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
@@ -2928,6 +2993,25 @@
"node": ">=4.0"
}
},
+ "node_modules/jwa": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
+ "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
+ "dependencies": {
+ "buffer-equal-constant-time": "1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/jws": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
+ "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+ "dependencies": {
+ "jwa": "^1.4.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -2998,12 +3082,47 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/lodash.includes": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
+ "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
+ },
+ "node_modules/lodash.isboolean": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+ "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
+ },
+ "node_modules/lodash.isinteger": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+ "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
+ },
+ "node_modules/lodash.isnumber": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+ "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
+ },
+ "node_modules/lodash.isplainobject": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
+ },
+ "node_modules/lodash.isstring": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+ "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
+ },
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true
},
+ "node_modules/lodash.once": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
+ },
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -3019,7 +3138,6 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
"dependencies": {
"yallist": "^4.0.0"
},
@@ -3101,8 +3219,7 @@
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "dev": true
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/mz": {
"version": "2.7.0",
@@ -4010,6 +4127,25 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
"node_modules/safe-regex-test": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
@@ -4036,7 +4172,6 @@
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
- "dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
@@ -4700,8 +4835,7 @@
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
- "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
- "dev": true
+ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
},
"node_modules/update-browserslist-db": {
"version": "1.0.13",
@@ -4962,8 +5096,7 @@
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/yaml": {
"version": "2.3.4",
diff --git a/weatherfit_refactoring/package.json b/weatherfit_refactoring/package.json
index 74dddee..dba5090 100644
--- a/weatherfit_refactoring/package.json
+++ b/weatherfit_refactoring/package.json
@@ -10,8 +10,11 @@
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,css,scss,md}\""
},
"dependencies": {
+ "@types/jsonwebtoken": "^9.0.6",
"axios": "^1.6.7",
+ "dompurify": "^3.0.11",
"js-cookie": "^3.0.5",
+ "jsonwebtoken": "^9.0.2",
"next": "14.0.4",
"react": "^18",
"react-dom": "^18",
@@ -21,6 +24,7 @@
"zustand": "^4.4.7"
},
"devDependencies": {
+ "@types/dompurify": "^3.0.5",
"@types/js-cookie": "^3.0.6",
"@types/node": "^20",
"@types/react": "^18",
diff --git a/weatherfit_refactoring/public/images/question.bmp b/weatherfit_refactoring/public/images/question.bmp
new file mode 100644
index 0000000..9c59ed9
Binary files /dev/null and b/weatherfit_refactoring/public/images/question.bmp differ
diff --git a/weatherfit_refactoring/src/Components/Atoms/Button/ButtonStore.tsx b/weatherfit_refactoring/src/Components/Atoms/Button/ButtonStore.tsx
index 80729aa..a4e42fa 100644
--- a/weatherfit_refactoring/src/Components/Atoms/Button/ButtonStore.tsx
+++ b/weatherfit_refactoring/src/Components/Atoms/Button/ButtonStore.tsx
@@ -75,7 +75,7 @@ export default function ButtonStore({
case ButtonStyle.CATEGORY_BTN_Y:
return (
diff --git a/weatherfit_refactoring/src/Components/Molecules/BestThreeCodi.tsx b/weatherfit_refactoring/src/Components/Molecules/BestThreeCodi.tsx
index 4c62309..f41fe19 100644
--- a/weatherfit_refactoring/src/Components/Molecules/BestThreeCodi.tsx
+++ b/weatherfit_refactoring/src/Components/Molecules/BestThreeCodi.tsx
@@ -4,11 +4,23 @@ import Image from 'next/image'
export default function BestThreeCodi({ data }: { data?: FEEDDATA_detail }) {
if (!data || !data.images) {
- return null
+ return (
+
+
+
+
+
+ )
}
return (
- <>
+
{data.images.map((image, index) => (
@@ -23,6 +35,6 @@ export default function BestThreeCodi({ data }: { data?: FEEDDATA_detail }) {
// 유저 정보 넣어야 함
))}
- >
+
)
}
diff --git a/weatherfit_refactoring/src/Components/Molecules/DetailCategory.tsx b/weatherfit_refactoring/src/Components/Molecules/DetailCategory.tsx
index 77ae3df..6307880 100644
--- a/weatherfit_refactoring/src/Components/Molecules/DetailCategory.tsx
+++ b/weatherfit_refactoring/src/Components/Molecules/DetailCategory.tsx
@@ -71,6 +71,7 @@ export default function DetailCategory({
)
}
+
function setFeedData(toJson: any) {
throw new Error('Function not implemented.')
}
diff --git a/weatherfit_refactoring/src/Components/Molecules/DetailContent.tsx b/weatherfit_refactoring/src/Components/Molecules/DetailContent.tsx
index db97da5..4b54a71 100644
--- a/weatherfit_refactoring/src/Components/Molecules/DetailContent.tsx
+++ b/weatherfit_refactoring/src/Components/Molecules/DetailContent.tsx
@@ -1,4 +1,5 @@
'use client'
+import DOMPurify from 'dompurify'
import { FeedData } from '@/Store/FeedData'
import { useRouter } from 'next/navigation'
@@ -37,27 +38,28 @@ export default function DetailContent({
const result: JSX.Element[] = []
splitContent.forEach((current, index) => {
- const replacedContent = current
+ const cleanedContent = DOMPurify.sanitize(current)
.replace(/\n/g, '
')
.replace(/ /g, ' ')
result.push(
,
)
if (index !== splitContent.length - 1) {
const currentHashTag = matchedHashTags[index]
- const tagIndex = hashTag.indexOf(currentHashTag.slice(1))
+ const cleanedHashTag = DOMPurify.sanitize(currentHashTag)
+ const tagIndex = hashTag.indexOf(cleanedHashTag.slice(1))
result.push(
handleHashTagClick(currentHashTag)}>
- {currentHashTag}
+ onClick={() => handleHashTagClick(cleanedHashTag)}>
+ {cleanedHashTag}
,
)
}
@@ -68,7 +70,6 @@ export default function DetailContent({
return (
- {/* 추후에 더보기 접기 버튼 넣어야 할 듯 */}
{nickName}
{extractAndStyleHashtags(content)}
diff --git a/weatherfit_refactoring/src/Components/Molecules/DetailEtc.tsx b/weatherfit_refactoring/src/Components/Molecules/DetailEtc.tsx
index 1421ebc..fd40568 100644
--- a/weatherfit_refactoring/src/Components/Molecules/DetailEtc.tsx
+++ b/weatherfit_refactoring/src/Components/Molecules/DetailEtc.tsx
@@ -1,15 +1,29 @@
'use client'
import { useState } from 'react'
+import jwt from 'jsonwebtoken'
import IconStore, { IconStyle } from '../Atoms/Icon/IconStore'
import ButtonStore, { ButtonStyle } from '../Atoms/Button/ButtonStore'
import { usePathname, useRouter } from 'next/navigation'
import { deleteAlert, deleteOkAlert } from '@/utils/function/utilFunction'
+import { AuthTokenStore } from '@/Store/AuthToken'
-export default function DetailEtc(boardId: BOARDID) {
+export default function DetailEtc({
+ boardId,
+ nickName,
+}: {
+ boardId: BOARDID
+ nickName: string
+}) {
const [isDropdownOpen, setIsDropdownOpen] = useState(false)
+ const { accesstoken } = AuthTokenStore()
+ const decodedToken = accesstoken
+ ? (jwt.decode(accesstoken) as { [key: string]: any })
+ : null
+ const decoded_nickName = decodedToken?.sub
const router = useRouter()
const currentUrl = usePathname()
+
const handleEdit = () => {
router.push(`${currentUrl}/edit`)
}
@@ -23,9 +37,7 @@ export default function DetailEtc(boardId: BOARDID) {
{
method: 'DELETE',
headers: {
- // Authorization: 'Bearer ' + logintoken,
- Authorization:
- 'Bearer eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE3MDY3OTA5MDEsImV4cCI6MTcwNjgwMTcwMSwic3ViIjoi7YWM7Iqk7YSwNTUifQ.sdm2nHun06cOIeWzXFv8xSbuuhY_yCsiRT7Upu1vtIs',
+ Authorization: 'Bearer ' + accesstoken,
},
},
)
@@ -45,12 +57,15 @@ export default function DetailEtc(boardId: BOARDID) {
return (
<>
- setIsDropdownOpen(!isDropdownOpen)}
- />
+ {' '}
+ {decoded_nickName === nickName ? (
+ setIsDropdownOpen(!isDropdownOpen)}
+ />
+ ) : null}
{isDropdownOpen && (
+ onClickFunction={() => onClickFunction}>
{btnText}
) : iconStyleCase ? (
diff --git a/weatherfit_refactoring/src/Components/Molecules/LikeAndComment.tsx b/weatherfit_refactoring/src/Components/Molecules/LikeAndComment.tsx
index 9844fbf..2b524bc 100644
--- a/weatherfit_refactoring/src/Components/Molecules/LikeAndComment.tsx
+++ b/weatherfit_refactoring/src/Components/Molecules/LikeAndComment.tsx
@@ -1,10 +1,42 @@
+'use client'
+
+import { useStore } from '@/Store/Store'
import IconStore, { IconStyle } from '../Atoms/Icon/IconStore'
import CommentIcon from './CommentIcon'
+import { AuthTokenStore } from '@/Store/AuthToken'
+
+export default function LikeAndComment({ boardId }: { boardId: BOARDID }) {
+ const { isLiked, toggleLikeState } = useStore()
+ const { accesstoken } = AuthTokenStore()
+
+ const toggleLike = async () => {
+ try {
+ const response = await fetch(
+ `https://www.yourwebsite.com/board/like/${boardId}`,
+ {
+ method: 'POST',
+ headers: {
+ Authorization: 'Bearer ' + accesstoken,
+ },
+ },
+ )
+ if (!response.ok) {
+ throw new Error('Network response was not ok.')
+ }
+ toggleLikeState()
+ } catch (error) {
+ console.error('좋아요 실패:', error)
+ }
+ }
-export default function LikeAndComment() {
return (
)
diff --git a/weatherfit_refactoring/src/Components/Molecules/TextAreaMolecule.tsx b/weatherfit_refactoring/src/Components/Molecules/TextAreaMolecule.tsx
index d5e1a02..f83ba8e 100644
--- a/weatherfit_refactoring/src/Components/Molecules/TextAreaMolecule.tsx
+++ b/weatherfit_refactoring/src/Components/Molecules/TextAreaMolecule.tsx
@@ -7,17 +7,24 @@ import { extractHashtags } from '@/utils/function/utilFunction'
export default function TextAreaMolecule({
initContent,
+ mode,
}: {
initContent?: FEEDDATA_detail['content']
+ mode: 'edit' | 'upload'
}) {
const { content, setContent, setHashTag } = useStore()
const textAreaRef = useRef
(null)
useEffect(() => {
- if (initContent) {
+ // Edit 모드일 때는 initContent로 초기화
+ if (mode === 'edit' && initContent) {
setContent(initContent)
}
- }, [setContent])
+ // Upload 모드일 때는 내용을 비워준다
+ if (mode === 'upload') {
+ setContent('')
+ }
+ }, [initContent, mode, setContent])
const handleChange = () => {
if (textAreaRef.current) {
diff --git a/weatherfit_refactoring/src/Components/Organisms/DetailOrganism.tsx b/weatherfit_refactoring/src/Components/Organisms/DetailOrganism.tsx
index 09e063d..4d3ef2e 100644
--- a/weatherfit_refactoring/src/Components/Organisms/DetailOrganism.tsx
+++ b/weatherfit_refactoring/src/Components/Organisms/DetailOrganism.tsx
@@ -1,12 +1,16 @@
import DetailContent from '@/Components/Molecules/DetailContent'
-import DetailImage from '@/Components/Molecules/DetailImge'
+import DetailImage from '@/Components/Molecules/DetailImage'
import DetailCategory from '../Molecules/DetailCategory'
import LikeAndComment from '../Molecules/LikeAndComment'
import DetailProfile from '../Molecules/DetailProfile'
import DetailEtc from '../Molecules/DetailEtc'
import NotFound from '@/app/not-found'
-export default async function DetailOrganism({ boardId }: BOARDID) {
+export default async function DetailOrganism({
+ boardId,
+}: {
+ boardId: BOARDID
+}) {
const fetchBoardDataResponse = await fetch(
`https://www.jerneithe.site/board/detail/${boardId}`,
{
@@ -39,10 +43,10 @@ export default async function DetailOrganism({ boardId }: BOARDID) {
nickName={fetchBoardData.nickName}
userData={fetchUserData}
/>
-
+
-
+
{
+ if (selectedImages.length === 0) {
+ alert('업로드 된 사진이 없습니다.')
+ return // 함수를 여기서 종료하여 더 이상 진행하지 않습니다.
+ }
+
+ if (category.length === 0) {
+ alert('선택된 카테고리가 없습니다.')
+ return // 함수를 여기서 종료합니다.
+ }
+
try {
const formData = new FormData()
const boardData = {
@@ -36,18 +48,17 @@ export default function EditHeader(boardId: BOARDID) {
body: formData,
headers: {
'Content-Type': 'multipart/form-data',
- // Authorization: 'Bearer ' + accessToken,
+ Authorization: 'Bearer ' + accesstoken,
},
},
)
- console.log(response)
- console.log('수정 버튼 클릭')
- console.log('content: ', content)
- console.log('hashTag: ', hashTag)
- const images = formData.getAll('images')
- console.log('images: ', images)
- console.log('category', category)
+ if (response.ok) {
+ alert('수정이 완료되었습니다.')
+ window.location.href = `/detail/${boardId}`
+ } else {
+ alert('수정에 실패했습니다. 다시 시도해주세요.')
+ }
} catch (error) {
console.error(error)
}
diff --git a/weatherfit_refactoring/src/Components/Organisms/EditOrganism.tsx b/weatherfit_refactoring/src/Components/Organisms/EditOrganism.tsx
index a87eb71..fbbfe5b 100644
--- a/weatherfit_refactoring/src/Components/Organisms/EditOrganism.tsx
+++ b/weatherfit_refactoring/src/Components/Organisms/EditOrganism.tsx
@@ -19,11 +19,11 @@ export default async function EditOrganism({ boardId }: BOARDID) {
)
diff --git a/weatherfit_refactoring/src/Components/Organisms/ImageUpload.tsx b/weatherfit_refactoring/src/Components/Organisms/ImageUpload.tsx
index 78c0c22..ad324de 100644
--- a/weatherfit_refactoring/src/Components/Organisms/ImageUpload.tsx
+++ b/weatherfit_refactoring/src/Components/Organisms/ImageUpload.tsx
@@ -7,8 +7,10 @@ import ArrayImage from '../Molecules/ArrayImage'
export default function ImageUpload({
images,
+ mode,
}: {
images?: FEEDDATA_detail['images']
+ mode: 'edit' | 'upload'
}) {
const {
selectedImages,
@@ -17,14 +19,16 @@ export default function ImageUpload({
setExistingImages,
setDeletedImages,
} = useStore()
- // const [existingImages, setExistingImages] = useState([])
- const initialImages = images
useEffect(() => {
- if (initialImages) {
- setExistingImages(initialImages)
+ if (mode === 'edit' && images) {
+ setExistingImages(images)
+ } else if (mode === 'upload') {
+ // Upload 모드에서는 선택된 이미지와 기존 이미지 모두 초기화
+ setSelectedImages([])
+ setExistingImages([])
}
- }, [initialImages])
+ }, [mode, images, setExistingImages, setSelectedImages])
const handleImagesSelected = useCallback((files: File[] | null) => {
setSelectedImages(files ? Array.from(files) : [])
diff --git a/weatherfit_refactoring/src/Components/Organisms/SelectCategory.tsx b/weatherfit_refactoring/src/Components/Organisms/SelectCategory.tsx
index d58fca8..2e73e3a 100644
--- a/weatherfit_refactoring/src/Components/Organisms/SelectCategory.tsx
+++ b/weatherfit_refactoring/src/Components/Organisms/SelectCategory.tsx
@@ -7,8 +7,10 @@ import { useStore } from '../../Store/Store'
export default function SelectCategory({
initCategory,
+ mode,
}: {
initCategory?: FEEDDATA_detail['category']
+ mode: 'edit' | 'upload'
}) {
const { setSelectedSubCategories } = useStore()
@@ -26,7 +28,9 @@ export default function SelectCategory({
key={category}
category={category}
subCategories={subCategories}
- initialSelectedSubCategories={initCategory}
+ initialSelectedSubCategories={
+ mode === 'edit' ? initCategory : undefined
+ }
onSelect={selectedSubCategories =>
handleCategorySelect(category, selectedSubCategories)
}
diff --git a/weatherfit_refactoring/src/Components/Organisms/UploadHeader.tsx b/weatherfit_refactoring/src/Components/Organisms/UploadHeader.tsx
index d13643c..c19ce69 100644
--- a/weatherfit_refactoring/src/Components/Organisms/UploadHeader.tsx
+++ b/weatherfit_refactoring/src/Components/Organisms/UploadHeader.tsx
@@ -3,14 +3,26 @@ import Header from '../Molecules/Header'
import { useStore } from '../../Store/Store'
import { WeatherIcon } from '@/Store/WeatherIcon'
import { WeatherTemp } from '@/Store/WeatherTemp'
+import { AuthTokenStore } from '@/Store/AuthToken'
export default function UploadHeader() {
const { content, hashTag, selectedImages, selectedSubCategories } = useStore()
const category = Object.values(selectedSubCategories).flat() // 하위 카테고리들만 저장
const { weatherIcon } = WeatherIcon()
const { temperature } = WeatherTemp()
+ const { accesstoken } = AuthTokenStore()
const handleOnClick = async () => {
+ if (selectedImages.length === 0) {
+ alert('업로드 된 사진이 없습니다.')
+ return // 함수를 여기서 종료하여 더 이상 진행하지 않습니다.
+ }
+
+ if (category.length === 0) {
+ alert('선택된 카테고리가 없습니다.')
+ return // 함수를 여기서 종료합니다.
+ }
+
try {
const formData = new FormData()
const boardData = {
@@ -31,17 +43,16 @@ export default function UploadHeader() {
body: formData,
headers: {
'Content-Type': 'multipart/form-data',
- // Authorization: 'Bearer ' + accessToken,
+ Authorization: 'Bearer ' + accesstoken,
},
})
- console.log(response)
- console.log('등록 버튼 클릭')
- console.log('content: ', content) //ok
- console.log('hashTag: ', hashTag) //ok
- const images = formData.getAll('images')
- console.log('images: ', images)
- console.log('selected categories', category)
+ if (response.ok) {
+ alert('업로드 되었습니다.')
+ window.location.href = `/feed`
+ } else {
+ alert('업로드에 실패했습니다. 다시 시도해주세요.')
+ }
} catch (error) {
console.error(error)
}
diff --git a/weatherfit_refactoring/src/Store/Store.ts b/weatherfit_refactoring/src/Store/Store.ts
index bc5eb1b..958d32c 100644
--- a/weatherfit_refactoring/src/Store/Store.ts
+++ b/weatherfit_refactoring/src/Store/Store.ts
@@ -15,6 +15,9 @@ interface State {
setInitialSubCategories: (initialSubCategories: string[]) => void
deletedImages: number[]
setDeletedImages: (imageId: number) => void
+ // 좋아요
+ isLiked: boolean
+ toggleLikeState: () => void
}
export const useStore = create(set => ({
@@ -50,4 +53,6 @@ export const useStore = create(set => ({
deletedImages: [...state.deletedImages, imageId],
}))
},
+ isLiked: false,
+ toggleLikeState: () => set(state => ({ isLiked: !state.isLiked })),
}))
diff --git a/weatherfit_refactoring/src/app/detail/[id]/page.tsx b/weatherfit_refactoring/src/app/detail/[id]/page.tsx
index 7aadf0c..230a672 100644
--- a/weatherfit_refactoring/src/app/detail/[id]/page.tsx
+++ b/weatherfit_refactoring/src/app/detail/[id]/page.tsx
@@ -2,7 +2,7 @@ import Header from '@/Components/Molecules/Header'
import WeatherNavbar from '@/Components/Molecules/WeatherNavbar'
import DetailOrganism from '@/Components/Organisms/DetailOrganism'
-export default function Detail({ params }: { params: { id: string } }) {
+export default function Detail({ params }: { params: { id: BOARDID } }) {
const { id: boardId } = params
return (
diff --git a/weatherfit_refactoring/src/app/upload/page.tsx b/weatherfit_refactoring/src/app/upload/page.tsx
index 3403538..fd1f5ae 100644
--- a/weatherfit_refactoring/src/app/upload/page.tsx
+++ b/weatherfit_refactoring/src/app/upload/page.tsx
@@ -5,20 +5,48 @@ import TextAreaMolecule from '@/Components/Molecules/TextAreaMolecule'
import SelectCategory from '@/Components/Organisms/SelectCategory'
import UploadHeader from '@/Components/Organisms/UploadHeader'
import UploadWeather from '@/Components/Molecules/UploadWeather'
+import Loading from '@/Components/Organisms/Loading'
+import NoLogin from '@/Components/Organisms/NoLogin'
+import { LoadingStore } from '@/Store/Loading'
+import { CheckStore } from '@/Store/Check'
+import { AuthTokenStore } from '@/Store/AuthToken'
+import { loginCheck } from '@/utils/function/utilFunction'
+import { useEffect } from 'react'
export default function Upload() {
+ const { loading, setLoading } = LoadingStore()
+ const { accesstoken, setAccessToken } = AuthTokenStore()
+ const { check, setCheck } = CheckStore()
+
+ useEffect(() => {
+ setAccessToken()
+ loginCheck(accesstoken, setCheck, setLoading)
+ }, [accesstoken])
+
return (
-
+ <>
+ {loading ? (
+
+ ) : (
+ <>
+ {check ? (
+
+ ) : (
+
+ )}
+ >
+ )}
+ >
)
}