diff --git a/package-lock.json b/package-lock.json
index ef6c6e3..9ffa87a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -26,6 +26,8 @@
"react-datepicker": "^6.9.0",
"react-dom": "^18",
"react-hook-form": "^7.51.2",
+ "react-query": "^3.39.3",
+ "react-toastify": "^10.0.5",
"rsuite": "^5.58.1",
"styled-components": "^6.1.8"
},
@@ -7773,8 +7775,7 @@
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/bare-events": {
"version": "2.2.2",
@@ -7849,7 +7850,6 @@
"version": "1.6.52",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
"integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==",
- "dev": true,
"engines": {
"node": ">=0.6"
}
@@ -8005,7 +8005,6 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -8023,6 +8022,21 @@
"node": ">=8"
}
},
+ "node_modules/broadcast-channel": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz",
+ "integrity": "sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==",
+ "dependencies": {
+ "@babel/runtime": "^7.7.2",
+ "detect-node": "^2.1.0",
+ "js-sha3": "0.8.0",
+ "microseconds": "0.2.0",
+ "nano-time": "1.0.0",
+ "oblivious-set": "1.0.0",
+ "rimraf": "3.0.2",
+ "unload": "2.2.0"
+ }
+ },
"node_modules/brorand": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
@@ -8768,8 +8782,7 @@
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
"node_modules/consola": {
"version": "3.2.3",
@@ -9503,6 +9516,11 @@
"node": ">=8"
}
},
+ "node_modules/detect-node": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
+ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="
+ },
"node_modules/detect-package-manager": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/detect-package-manager/-/detect-package-manager-2.0.1.tgz",
@@ -11302,8 +11320,7 @@
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "dev": true
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"node_modules/fsevents": {
"version": "2.3.3",
@@ -12086,7 +12103,6 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "dev": true,
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
@@ -12095,8 +12111,7 @@
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "dev": true
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/ini": {
"version": "1.3.8",
@@ -12754,6 +12769,11 @@
"jiti": "bin/jiti.js"
}
},
+ "node_modules/js-sha3": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
+ "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q=="
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -13155,6 +13175,15 @@
"react": ">= 0.14.0"
}
},
+ "node_modules/match-sorter": {
+ "version": "6.3.4",
+ "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.4.tgz",
+ "integrity": "sha512-jfZW7cWS5y/1xswZo8VBOdudUiSd9nifYRWphc9M5D/ee4w4AoXLgBEdRbgVaxbMuagBPeUC5y2Hi8DO6o9aDg==",
+ "dependencies": {
+ "@babel/runtime": "^7.23.8",
+ "remove-accents": "0.5.0"
+ }
+ },
"node_modules/md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -13249,6 +13278,11 @@
"node": ">=8.6"
}
},
+ "node_modules/microseconds": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz",
+ "integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA=="
+ },
"node_modules/miller-rabin": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
@@ -13345,7 +13379,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -13427,6 +13460,14 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
+ "node_modules/nano-time": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz",
+ "integrity": "sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==",
+ "dependencies": {
+ "big-integer": "^1.6.16"
+ }
+ },
"node_modules/nanoid": {
"version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
@@ -13983,6 +14024,11 @@
"integrity": "sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg==",
"dev": true
},
+ "node_modules/oblivious-set": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz",
+ "integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw=="
+ },
"node_modules/ohash": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.3.tgz",
@@ -14014,7 +14060,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "dev": true,
"dependencies": {
"wrappy": "1"
}
@@ -14250,7 +14295,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -15747,6 +15791,31 @@
"react-dom": "^15.5.x || ^16.x || ^17.x || ^18.x"
}
},
+ "node_modules/react-query": {
+ "version": "3.39.3",
+ "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz",
+ "integrity": "sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g==",
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "broadcast-channel": "^3.4.1",
+ "match-sorter": "^6.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
+ }
+ },
"node_modules/react-refresh": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
@@ -15756,6 +15825,18 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-toastify": {
+ "version": "10.0.5",
+ "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.5.tgz",
+ "integrity": "sha512-mNKt2jBXJg4O7pSdbNUfDdTsK9FIdikfsIE/yUCxbAEXl4HMyJaivrVFcn3Elvt5xvCQYhUZm+hqTIu1UXM3Pw==",
+ "dependencies": {
+ "clsx": "^2.1.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ }
+ },
"node_modules/react-use-set": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/react-use-set/-/react-use-set-1.0.0.tgz",
@@ -16113,6 +16194,11 @@
"node": ">= 0.10"
}
},
+ "node_modules/remove-accents": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz",
+ "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A=="
+ },
"node_modules/renderkid": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz",
@@ -16272,7 +16358,6 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
"dependencies": {
"glob": "^7.1.3"
},
@@ -16287,7 +16372,6 @@
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@@ -18245,6 +18329,15 @@
"node": ">= 10.0.0"
}
},
+ "node_modules/unload": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz",
+ "integrity": "sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==",
+ "dependencies": {
+ "@babel/runtime": "^7.6.2",
+ "detect-node": "^2.0.4"
+ }
+ },
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@@ -18834,8 +18927,7 @@
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "dev": true
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"node_modules/write-file-atomic": {
"version": "2.4.3",
diff --git a/package.json b/package.json
index 46dbdf6..f66e0f4 100644
--- a/package.json
+++ b/package.json
@@ -29,6 +29,8 @@
"react-datepicker": "^6.9.0",
"react-dom": "^18",
"react-hook-form": "^7.51.2",
+ "react-query": "^3.39.3",
+ "react-toastify": "^10.0.5",
"rsuite": "^5.58.1",
"styled-components": "^6.1.8"
},
diff --git a/src/apis/http.tsx b/src/apis/http.tsx
index eb43464..2629ec4 100644
--- a/src/apis/http.tsx
+++ b/src/apis/http.tsx
@@ -58,7 +58,7 @@ axiosInstance.interceptors.response.use(
console.log(err);
// access token 만료 시
if (response?.status && response?.status === 403) {
- window.location.href = "/login";
+ window.location.href = "/user/login";
localStorage.clear();
return config;
}
diff --git a/src/app/info/board/like/page.tsx b/src/app/info/board/like/page.tsx
new file mode 100644
index 0000000..3cf9e0c
--- /dev/null
+++ b/src/app/info/board/like/page.tsx
@@ -0,0 +1,11 @@
+import { InfoBoardLike } from "@/features/info/board/like/InfoBoardLike";
+
+const InfoBoardLikePage = () => {
+ return (
+ <>
+
+ >
+ );
+};
+
+export default InfoBoardLikePage;
diff --git a/src/app/user/club/page.tsx b/src/app/user/club/create/page.tsx
similarity index 67%
rename from src/app/user/club/page.tsx
rename to src/app/user/club/create/page.tsx
index 17c54f5..20b17db 100644
--- a/src/app/user/club/page.tsx
+++ b/src/app/user/club/create/page.tsx
@@ -1,8 +1,8 @@
import SetupUserClub from "@/features/user/club/SetupUserClub";
-const UserClub = () => {
+const UserClubCreate = () => {
// 모임 등록 페이지
return ;
}
-export default UserClub;
\ No newline at end of file
+export default UserClubCreate;
\ No newline at end of file
diff --git a/src/app/user/club/join/[clubId]/page.tsx b/src/app/user/club/join/[clubId]/page.tsx
new file mode 100644
index 0000000..f248f88
--- /dev/null
+++ b/src/app/user/club/join/[clubId]/page.tsx
@@ -0,0 +1,7 @@
+import InvitationCode from "@/features/user/joinClub/InvitationCode";
+
+const JoinClubInfo = () => {
+ return ;
+};
+
+export default JoinClubInfo;
diff --git a/src/app/user/join/page.tsx b/src/app/user/club/join/page.tsx
similarity index 100%
rename from src/app/user/join/page.tsx
rename to src/app/user/club/join/page.tsx
diff --git a/src/app/login/page.tsx b/src/app/user/login/page.tsx
similarity index 61%
rename from src/app/login/page.tsx
rename to src/app/user/login/page.tsx
index c9abb93..30cc0dc 100644
--- a/src/app/login/page.tsx
+++ b/src/app/user/login/page.tsx
@@ -1,4 +1,4 @@
-import Login from "@/features/Login/Login";
+import Login from "@/features/user/Login/Login";
const UserLogin = () => {
return ;
diff --git a/src/assets/images/ic_header_menuToggle.png b/src/assets/images/ic_header_menuToggle.png
new file mode 100644
index 0000000..7031ab2
Binary files /dev/null and b/src/assets/images/ic_header_menuToggle.png differ
diff --git a/src/components/atoms/comment/Comment.css b/src/components/atoms/comment/Comment.css
index 09aa3c6..a3486f3 100644
--- a/src/components/atoms/comment/Comment.css
+++ b/src/components/atoms/comment/Comment.css
@@ -1,10 +1,11 @@
.comment__box {
display: flex;
align-items: center;
- width:fit-content;
+ width: 100%;
}
.comment__box__wrapper {
margin-top: 0.94rem;
+ width: 100%;
}
.comment__box__is__reply img {
width: 0.875rem;
@@ -15,6 +16,7 @@
.comment__box__profile {
display: flex;
align-items: center;
+ width: 100%;
}
.comment__box__profile img {
width: 1.8125rem;
@@ -27,10 +29,9 @@
margin-bottom: 0.31rem;
display: flex;
flex-direction: column;
+ margin-right: auto;
}
-.comment__box__edit {
- margin-left: auto;
-}
+
.comment__box__margin__left {
margin-left: 2.4125rem;
}
diff --git a/src/components/atoms/comment/Comment.tsx b/src/components/atoms/comment/Comment.tsx
index 5fea591..93abe02 100644
--- a/src/components/atoms/comment/Comment.tsx
+++ b/src/components/atoms/comment/Comment.tsx
@@ -1,52 +1,47 @@
import replyIcon from "@/assets/images/reply.png";
-import Image, { StaticImageData } from "next/image";
+import { IMAGES } from "@/constants/images";
+import { useCommentDeleteMutation } from "@/hook/comment/useCommentDeleteMutation";
+import { CommentsProps } from "@/types/comment";
+import Image from "next/image";
+import { usePathname } from "next/navigation";
import { Text } from "../text";
import "./Comment.css";
-export interface CommentProps {
- commentId: number;
- createdAt: string;
- isEditAllowed: boolean; //댓글 작성자와 동일일 경우 수정
- memberInfo: {
- profile: StaticImageData;
- name: string;
- };
- content: string;
- parentId?: number; //대댓글일경우 필요
- reply?: boolean; // 대댓글일 경우 true
- onClick?: () => void; //대댓글 작성 핸들러
-}
-export function Comment({
- commentId,
- createdAt,
- isEditAllowed,
- memberInfo: { profile, name },
- content,
- parentId,
- reply,
- onClick,
-}: CommentProps) {
+export function Comment({ item, onClick }: CommentsProps) {
+ const path = usePathname();
+ const pathProps = path.split("/").slice(1);
+ const { mutate: deleteCommentMutate } = useCommentDeleteMutation({
+ clubId: parseInt(pathProps[0], 10),
+ postId: parseInt(pathProps[3], 10),
+ commentId: item.commentId,
+ });
+ const handleDeleteComment = () => {
+ deleteCommentMutate();
+ };
+ const handleReplyClick = () => {
+ onClick(item.commentId);
+ };
return (
- {reply && (
+ {item.parentId && (
)}
-
+
- {name}
+ 이름자리
- {createdAt}
+ {item.createdAt}
{/* 유저 정보 비교 후 동일하다면 */}
- {isEditAllowed && (
+ {item.memberId && (
수정
@@ -54,7 +49,12 @@ export function Comment({
|
-
+
삭제
@@ -63,12 +63,17 @@ export function Comment({
- {content}
+ {item.content}
- {!reply && (
+ {!item.parentId && (
-
+
답글 쓰기
diff --git a/src/components/atoms/comment/CommentInput.tsx b/src/components/atoms/comment/CommentInput.tsx
index 1a0c6dc..edb6806 100644
--- a/src/components/atoms/comment/CommentInput.tsx
+++ b/src/components/atoms/comment/CommentInput.tsx
@@ -1,24 +1,66 @@
import submitIcon from "@/assets/images/ic_commentSubmit.png";
+import { useCommentChildMutation } from "@/hook/comment/useCommentChildMutation";
+import { useCommentMutation } from "@/hook/comment/useCommentMutation";
+import { CommentData } from "@/types/comment";
import Image from "next/image";
-import React, { useState } from "react";
+import { usePathname } from "next/navigation";
+import { useForm } from "react-hook-form";
import "./CommentInput.css";
-export const CommentInput = () => {
- const [comment, setComment] = useState
("");
- const handleChange = (event: React.ChangeEvent) => {
- setComment(event.target.value);
+interface props {
+ parentId?: number;
+}
+export const CommentInput = ({ parentId }: props) => {
+ const path = usePathname();
+ const pathProps = path.split("/").slice(1);
+ const {
+ register,
+ formState: { errors },
+ reset,
+ handleSubmit,
+ } = useForm({
+ mode: "onSubmit",
+ defaultValues: {
+ postId: undefined,
+ content: "",
+ },
+ });
+ const { mutate: ToCommentMutate } = useCommentMutation({
+ clubId: parseInt(pathProps[0], 10),
+ postId: parseInt(pathProps[3], 10),
+ });
+ const { mutate: ToCommentChildMutate } = useCommentChildMutation({
+ clubId: parseInt(pathProps[0], 10),
+ postId: parseInt(pathProps[3], 10),
+ });
+ const onCommentSubmit = (data: CommentData) => {
+ const postData = {
+ ...data,
+ postId: parseInt(pathProps[3], 10),
+ };
+ ToCommentMutate(postData);
+ reset();
};
-
+ const onCommentChildSubmit = (data: CommentData) => {
+ const postData = {
+ ...data,
+ postId: parseInt(pathProps[3], 10),
+ parentId: parentId,
+ };
+ ToCommentChildMutate(postData);
+ reset();
+ };
+ const handleCommantFn =
+ parentId === undefined ? onCommentSubmit : onCommentChildSubmit;
return (
);
};
diff --git a/src/components/atoms/heart/Heart.tsx b/src/components/atoms/heart/Heart.tsx
index c68efd0..c1cb82c 100644
--- a/src/components/atoms/heart/Heart.tsx
+++ b/src/components/atoms/heart/Heart.tsx
@@ -16,7 +16,7 @@ export function Heart({
onClick,
}: ChipProps) {
return (
-
+
{hearts}
diff --git a/src/components/atoms/input/Input.tsx b/src/components/atoms/input/Input.tsx
index effacbe..8f308ac 100644
--- a/src/components/atoms/input/Input.tsx
+++ b/src/components/atoms/input/Input.tsx
@@ -1,8 +1,10 @@
// Input.tsx
"use client";
+import { COLORS } from "@/styles";
import { forwardRef, useState } from "react";
import { ControllerRenderProps } from "react-hook-form";
+import { Text } from "../text";
import "./input.css";
export interface InputProps {
@@ -50,8 +52,14 @@ export const Input = forwardRef(
/>
{maxCnt !== 0 && (
- {textCnt}
- /{maxCnt}
+ {textCnt}
+ /{maxCnt}
)}
diff --git a/src/components/atoms/input/input.css b/src/components/atoms/input/input.css
index 62f5cf8..e474fa5 100644
--- a/src/components/atoms/input/input.css
+++ b/src/components/atoms/input/input.css
@@ -1,7 +1,7 @@
.input__wrapper {
display: flex;
flex-direction: column;
- align-items: center;
+ align-items: flex-end;
justify-content: center;
gap: 0.3rem;
text-align: right;
@@ -21,6 +21,7 @@
cursor: pointer;
border-radius: 10px;
padding: 0 1rem;
+ font-family: "Pretendard Variable";
}
input::-webkit-input-placeholder {
diff --git a/src/components/atoms/search/Search.tsx b/src/components/atoms/search/Search.tsx
index d6af7da..0486cee 100644
--- a/src/components/atoms/search/Search.tsx
+++ b/src/components/atoms/search/Search.tsx
@@ -1,8 +1,33 @@
import { ICONS } from "@/constants/images";
import Image from "next/image";
+import { useEffect, useState } from "react";
+
+import { useDebounce } from "@/hook/schedule/useDebounce";
+import { ScheduleKeyword } from "@/types/schedule";
import "./Search.css";
-export const Search = () => {
+export interface SearchProps {
+ refetchKeywordSchedule: ({ keyword }: ScheduleKeyword) => void;
+}
+
+export const Search = ({
+ refetchKeywordSchedule
+}: SearchProps) => {
+ const [keyword, setKeyword] = useState('');
+ const debounceKeyword = useDebounce({keyword});
+
+ const handleSearch = (event: React.ChangeEvent
) => {
+ setKeyword(event.target.value);
+ };
+
+ useEffect(() => {
+ if(refetchKeywordSchedule){
+ refetchKeywordSchedule({
+ keyword
+ })
+ }
+ }, [debounceKeyword])
+
return(
{
alt="search"
/>
diff --git a/src/components/atoms/textarea/Textarea.tsx b/src/components/atoms/textarea/Textarea.tsx
index 190ce24..1145743 100644
--- a/src/components/atoms/textarea/Textarea.tsx
+++ b/src/components/atoms/textarea/Textarea.tsx
@@ -3,6 +3,8 @@
import React, { useState } from "react";
import { ControllerRenderProps } from "react-hook-form";
+import { COLORS } from "@/styles";
+import { Text } from "../text/Text";
import "./textarea.css";
export interface TextareaProps {
@@ -81,8 +83,14 @@ export function Textarea({
/>
{maxCnt !== undefined && (
- {textCnt}
- /{maxCnt}
+ {textCnt}
+ /{maxCnt}
)}
diff --git a/src/components/atoms/textarea/textarea.css b/src/components/atoms/textarea/textarea.css
index 28adb5d..04aacb2 100644
--- a/src/components/atoms/textarea/textarea.css
+++ b/src/components/atoms/textarea/textarea.css
@@ -5,6 +5,12 @@
line-height: 100%;
display: flex;
- align-items: center;
+ flex-direction: column;
+ align-items: flex-end;
justify-content: center;
+ gap: 0.5rem;
+}
+
+.textarea__wrapper > textarea {
+ font-family: "Pretendard Variable";
}
\ No newline at end of file
diff --git a/src/components/molecules/ImageModal/ImageModal.tsx b/src/components/molecules/ImageModal/ImageModal.tsx
index 3ed420c..f4f06c9 100644
--- a/src/components/molecules/ImageModal/ImageModal.tsx
+++ b/src/components/molecules/ImageModal/ImageModal.tsx
@@ -1,11 +1,11 @@
import { Arrow } from "@/components/atoms/arrow";
import { Text } from "@/components/atoms/text";
import _ from "lodash";
-import Image, { StaticImageData } from "next/image";
+import Image from "next/image";
import { useState } from "react";
import "./ImageModal.css";
interface ImageModalProps {
- imageList: StaticImageData[];
+ imageList: string[];
clickIndex: number;
onClose: () => void;
}
@@ -62,6 +62,8 @@ export const ImageModal = ({ imageList, clickIndex, onClose }: ImageModalProps)
src={imageList[currentIndex]}
alt="contentImg"
className="image__modal__image"
+ width={400}
+ height={400}
/>
handlePrevNext(-1)} isLeft={true} />
diff --git a/src/components/molecules/attendanceItem/AttendanceItem.tsx b/src/components/molecules/attendanceItem/AttendanceItem.tsx
index 0db28df..937ee05 100644
--- a/src/components/molecules/attendanceItem/AttendanceItem.tsx
+++ b/src/components/molecules/attendanceItem/AttendanceItem.tsx
@@ -15,14 +15,6 @@ const AttendanceItem = ({
scheduleTime,
onClick,
}: AttendanceSchedule) => {
- // if (attendanceStatus === "BEFORE") {
- // attendanceStatus = "미출석";
- // } else if (attendanceStatus === "ONGOING") {
- // attendanceStatus = "출석중";
- // } else if (attendanceStatus === "COMPLETE") {
- // attendanceStatus = "출석완료";
- // }
-
return (
diff --git a/src/components/molecules/commentList/CommentList.tsx b/src/components/molecules/commentList/CommentList.tsx
new file mode 100644
index 0000000..9667793
--- /dev/null
+++ b/src/components/molecules/commentList/CommentList.tsx
@@ -0,0 +1,17 @@
+import { Comment } from "@/components/atoms/comment";
+import { CommentsListProps } from "@/types/comment";
+
+export const CommentList = ({ item, replies, onClick }: CommentsListProps) => {
+ return (
+ <>
+
+ {replies &&
+ replies
+ .slice()
+ .reverse()
+ .map((comment, index: number) => (
+
+ ))}
+ >
+ );
+};
diff --git a/src/components/molecules/floatingBox/FloatingBox.tsx b/src/components/molecules/floatingBox/FloatingBox.tsx
index e166506..33b9d18 100644
--- a/src/components/molecules/floatingBox/FloatingBox.tsx
+++ b/src/components/molecules/floatingBox/FloatingBox.tsx
@@ -12,10 +12,10 @@ export function FloatingBox() {
setOn((prev) => !prev);
};
const handleRouteOnboarding = () => {
- router.push("/user/club");
+ router.push("/user/club/create");
};
const handleRouteJoin = () => {
- router.push("/user/join");
+ router.push("/user/club/join");
};
const inPlusStyle: React.CSSProperties = {
diff --git a/src/components/molecules/scheduleBox/ScheduleBox.css b/src/components/molecules/scheduleBox/ScheduleBox.css
index 3e3570f..a86edeb 100644
--- a/src/components/molecules/scheduleBox/ScheduleBox.css
+++ b/src/components/molecules/scheduleBox/ScheduleBox.css
@@ -17,7 +17,7 @@
.scheduleBox__content {
display: flex;
- width: 100%;
+ width: 60%;
gap: 1rem;
}
diff --git a/src/components/organisms/Header/BoardHeader.tsx b/src/components/organisms/Header/BoardHeader.tsx
new file mode 100644
index 0000000..dd03829
--- /dev/null
+++ b/src/components/organisms/Header/BoardHeader.tsx
@@ -0,0 +1,68 @@
+"use client";
+import { Text } from "@/components/atoms/text";
+import { ICONS, IMAGES } from "@/constants/images";
+import { usePostDeleteMutation } from "@/hook/post/usePostDeleteMutation";
+import Image from "next/image";
+import { usePathname, useRouter } from "next/navigation";
+import { useState } from "react";
+import "./Header.css";
+
+interface ClubHeaderProps {
+ color?: boolean;
+}
+export function BoardHeader({ color }: ClubHeaderProps) {
+ const pathname = usePathname();
+ const pathProps = pathname.split("/").slice(1);
+ const postItem = {
+ clubId: parseInt(pathProps[0], 10),
+ postId: parseInt(pathProps[3], 10),
+ };
+ const router = useRouter();
+ const [isOpenDropdown, setIsOpenDropdown] = useState(false);
+ const handleIsOpenDropdown = () => {
+ setIsOpenDropdown((prep) => !prep);
+ console.log(isOpenDropdown);
+ };
+ const { mutate: postDeleteMutate } = usePostDeleteMutation(postItem);
+ const menuItems = [
+ { text: "수정" },
+ { text: "삭제"},
+ { text: "URL 공유"},
+ ];
+ return (
+
+ );
+}
diff --git a/src/components/organisms/Header/Header.css b/src/components/organisms/Header/Header.css
index 9019f7d..87b5c48 100644
--- a/src/components/organisms/Header/Header.css
+++ b/src/components/organisms/Header/Header.css
@@ -7,7 +7,7 @@
justify-content: space-between;
height: 5.5rem;
padding: 0 5vw;
- background-color: #2B2B2B;
+ background-color: #2b2b2b;
position: fixed;
top: 0;
@@ -47,56 +47,95 @@
.logoHeader__img__right img {
margin-left: 0.69rem;
}
-.logoHeader__img__right img{
- margin-left: 0.69rem;
+.logoHeader__img__right img {
+ margin-left: 0.69rem;
+}
+
+/* boardHeader */
+.boardHeader {
+ background-color: #2b2b2b;
+ display: flex;
+ width: 100vw;
+ align-items: center;
+ justify-content: space-between;
+ height: 4.19rem;
+ padding-left: 5vw;
+ padding-right: 5vw;
+}
+
+.boardHeader.black {
+ background-color: #1b1b1b;
}
+.boardHeader img {
+ object-fit: contain;
+ width: 0.75rem;
+ height: 1.375rem;
+}
+
+.dropdown {
+ position: absolute;
+ top: 100%;
+ right: 0;
+ width: 7rem;
+ border-radius: 0.625rem;
+ background: #404040;
+ z-index: 10;
+ height: auto;
+}
+.underline {
+ border-bottom: 1px solid #fff;
+ padding: 0.7rem 0.5rem;
+}
+.underline:last-child {
+ border-bottom: none;
+}
/* clubHeader */
.clubHeader {
- background-color: #2B2B2B;
- display: flex;
- width: 100vw;
- align-items: center;
- justify-content: space-between;
- height: 5.5rem;
- padding-left: 5vw;
- padding-right: 5vw;
+ background-color: #2b2b2b;
+ display: flex;
+ width: 100vw;
+ align-items: center;
+ justify-content: space-between;
+ height: 5.5rem;
+ padding-left: 5vw;
+ padding-right: 5vw;
}
.clubHeader.black {
- background-color: #1B1B1B;
+ background-color: #1b1b1b;
}
.clubHeader img {
- object-fit: contain;
- height: 100%;
- width: 0.75rem;
- height: 1.375rem;
+ object-fit: contain;
+ height: 100%;
+ width: 0.75rem;
+ height: 1.375rem;
}
.clubHeader p {
width: 0.75rem;
- height: 1.375rem;
+ height: 1.375rem;
}
.clubHeader__title {
- display: flex;
- align-items: center;
- gap: 0.3rem;
- cursor: pointer;
+ display: flex;
+ align-items: center;
+ gap: 0.3rem;
+ cursor: pointer;
}
.clubHeader__title img {
- height: 0.375rem;
- width: 0.6875rem;
+ height: 0.375rem;
+ width: 0.6875rem;
}
.clubHeader__title__img.active {
- animation: rotate_img 0.3s linear forwards;
+ animation: rotate_img 0.3s linear forwards;
}
@keyframes rotate_img {
- 100% {
- transform: rotate(180deg);
- }
+ 100% {
+ transform: rotate(180deg);
+ }
}
diff --git a/src/components/organisms/Header/index.ts b/src/components/organisms/Header/index.ts
index 886f51f..2df1b49 100644
--- a/src/components/organisms/Header/index.ts
+++ b/src/components/organisms/Header/index.ts
@@ -1,3 +1,4 @@
+export { BoardHeader } from "./BoardHeader";
export { HistoryHeader } from "./HistoryHeader";
export { LogoHeader } from "./LogoHeader";
diff --git a/src/components/organisms/Modal/Modal.tsx b/src/components/organisms/Modal/Modal.tsx
index 7c52e16..34116b6 100644
--- a/src/components/organisms/Modal/Modal.tsx
+++ b/src/components/organisms/Modal/Modal.tsx
@@ -12,43 +12,48 @@ import { ModalTitle } from "./ModalTitle";
import styles from "./Modal.module.css";
// children 요소 중 Header filtering
-const ModalHeaderType= (
).type;
+const ModalDimmedType = (
).type;
+function getModalDimmed(children: ReactNode) {
+ const childrenArray = Children.toArray(children);
+ return childrenArray.filter(
+ (child) => isValidElement(child) && child.type === ModalDimmedType
+ );
+}
+
+// children 요소 중 Header filtering
+const ModalHeaderType = (
).type;
function getModalHeader(children: ReactNode) {
const childrenArray = Children.toArray(children);
- return childrenArray
- .filter(
- child => isValidElement(child) && child.type === ModalHeaderType,
- );
+ return childrenArray.filter(
+ (child) => isValidElement(child) && child.type === ModalHeaderType
+ );
}
// children 요소 중 Content filtering
-const ModalContentType= (
).type;
+const ModalContentType = (
).type;
function getModalContents(children: ReactNode) {
const childrenArray = Children.toArray(children);
- return childrenArray
- .filter(
- child => isValidElement(child) && child.type === ModalContentType,
- );
+ return childrenArray.filter(
+ (child) => isValidElement(child) && child.type === ModalContentType
+ );
}
// children 요소 중 Footer filtering
-const ModalFooterType= (
).type;
+const ModalFooterType = (
).type;
function getModalFooter(children: ReactNode) {
const childrenArray = Children.toArray(children);
- return childrenArray
- .filter(
- child => isValidElement(child) && child.type === ModalFooterType,
- )
+ return childrenArray.filter(
+ (child) => isValidElement(child) && child.type === ModalFooterType
+ );
}
-
interface ModalProps {
children?: ReactNode;
isOpen: boolean;
-};
+}
export const Modal = ({ children, isOpen }: ModalProps) => {
- if(!isOpen){
+ if (!isOpen) {
return null;
}
@@ -56,25 +61,19 @@ export const Modal = ({ children, isOpen }: ModalProps) => {
const modalContents = getModalContents(children);
const modalFooter = getModalFooter(children);
return createPortal(
-
- {
- modalHeader && (
-
{modalHeader}
- )
- }
- {
- modalContents && (
+ <>
+ {getModalDimmed(children)}
+
+ {modalHeader &&
{modalHeader}
}
+ {modalContents && (
{modalContents}
- )
- }
- {
- modalFooter && (
-
{modalFooter}
- )
- }
-
- , document.body);
-}
+ )}
+ {modalFooter &&
{modalFooter}
}
+
+ >,
+ document.body
+ );
+};
Modal.Dimmed = ModalDimmed;
Modal.Header = ModalHeader;
@@ -83,4 +82,4 @@ Modal.Footer = ModalFooter;
Modal.Title = ModalTitle;
Modal.Subtitle = ModalSubtitle;
-Modal.Button = ModalButtons;
\ No newline at end of file
+Modal.Button = ModalButtons;
diff --git a/src/components/organisms/Modal/ModalHeader.tsx b/src/components/organisms/Modal/ModalHeader.tsx
index a2ece2e..640b54f 100644
--- a/src/components/organisms/Modal/ModalHeader.tsx
+++ b/src/components/organisms/Modal/ModalHeader.tsx
@@ -2,16 +2,16 @@ import { IMAGES } from "@/constants/images";
import Image from "next/image";
import { ReactNode } from "react";
import styles from "./Modal.module.css";
-import { useModalContext } from "./ModalProvider";
interface ModalHeaderProps {
children?: ReactNode;
+ closeModal?: () => void;
}
export const ModalHeader = ({
- children
+ children,
+ closeModal
}: ModalHeaderProps) => {
- const { closeModal } = useModalContext();
return (
).type;
-function getModalDimmed(children: ReactNode) {
- const childrenArray = Children.toArray(children);
- return childrenArray
- .filter(
- child => isValidElement(child) && child.type === ModalDimmedType,
- )
- .slice(0, 1)[0] || null;
-}
-
-// children 요소 중 Header filtering
-const ModalHeaderType= (
).type;
-function getModalHeader(children: ReactNode) {
- const childrenArray = Children.toArray(children);
- return childrenArray
- .filter(
- child => isValidElement(child) && child.type === ModalHeaderType,
- );
-}
-
-// children 요소 중 Content filtering
-const ModalContentType= (
).type;
-function getModalContents(children: ReactNode) {
- const childrenArray = Children.toArray(children);
- return childrenArray
- .filter(
- child => isValidElement(child) && child.type === ModalContentType,
- );
-}
-
-// children 요소 중 Footer filtering
-const ModalFooterType= (
).type;
-function getModalFooter(children: ReactNode) {
- const childrenArray = Children.toArray(children);
- return childrenArray
- .filter(
- child => isValidElement(child) && child.type === ModalFooterType,
- )
-}
-
-interface ModalMainProps {
- children?: ReactNode;
- isOpen: boolean;
-};
-
-export const ModalMain = ({ children, isOpen }: ModalMainProps) => {
- if(!isOpen){
- return null;
- }
-
- const modalHeader = getModalHeader(children);
- const modalContents = getModalContents(children);
- const modalFooter = getModalFooter(children);
- return createPortal(
-
-
{getModalDimmed(children)}
- {
- modalHeader && (
-
{modalHeader}
- )
- }
- {
- modalContents && (
-
{modalContents}
- )
- }
- {
- modalFooter && (
-
{modalFooter}
- )
- }
-
- , document.body);
-}
diff --git a/src/constants/images.ts b/src/constants/images.ts
index 64c452b..354544e 100644
--- a/src/constants/images.ts
+++ b/src/constants/images.ts
@@ -12,6 +12,7 @@ export const IMAGES = {
};
export const ICONS = {
+ headerToggle: require("@/assets/images/ic_header_menuToggle.png"),
down: require("@/assets/images/ic_down.png"),
search: require("@/assets/images/ic_search.png"),
calendar: require("@/assets/images/ic_calendar.png"),
@@ -26,17 +27,17 @@ export const ICONS = {
back: require("@/assets/images/ic_back.png"),
filter: require("@/assets/images/ic_filter.png"),
nodata: require("@/assets/images/ic_nodata.png"),
-
+
floatingPlus: require("@/assets/images/Plus.png"),
floatingLock: require("@/assets/images/ic_lock.png"),
floatingMeeting: require("@/assets/images/ic_people.png"),
-
+
newBoard: require("@/assets/images/ic_new_board.png"),
comment: require("@/assets/images/ic_comment.png"),
-
+
heartColor: require("@/assets/images/ic_heartColor.png"),
heartNone: require("@/assets/images/ic_heartWhite.png"),
-
+
edit: require("@/assets/images/ic_edit.png"),
member: require("@/assets/images/ic_member.png"),
copy: require("@/assets/images/ic_copy.png"),
diff --git a/src/constants/keys/postKey.ts b/src/constants/keys/postKey.ts
new file mode 100644
index 0000000..895a2b6
--- /dev/null
+++ b/src/constants/keys/postKey.ts
@@ -0,0 +1,13 @@
+import { PostDetailProps } from "@/types/post";
+
+export const postKeys = {
+ all: ["post"] as const,
+ detail: ({ clubId, postId }: PostDetailProps) =>
+ [...postKeys.all, { clubId, postId }] as const,
+ comment: ({ clubId, postId }: PostDetailProps) =>
+ [...postKeys.detail({ clubId, postId }), "comment"] as const,
+};
+
+export const categoryKeys = {
+ all: ["categoty"] as const,
+};
diff --git a/src/features/board/components/Board.tsx b/src/features/board/components/Board.tsx
index f29e55f..c14dab7 100644
--- a/src/features/board/components/Board.tsx
+++ b/src/features/board/components/Board.tsx
@@ -2,16 +2,25 @@
import { Floating } from "@/components/atoms/floating";
import { Text } from "@/components/atoms/text";
import { ICONS } from "@/constants/images";
+import usePostListQuery from "@/hook/post/usePostListQuery";
import { usePathname, useRouter } from "next/navigation";
import React from "react";
-import { testArr } from "../constants/testArr/TestArr";
import "./Board.css";
import BoardItem from "./BoardItem";
const Board = () => {
const router = useRouter();
const pathname = usePathname();
+ const startedPath = pathname.split("/").slice(1)[0];
+ const clubId = parseInt(startedPath, 10);
const boardTypeAddress = pathname.split("/board/")[1];
+ const boardCategory = boardTypeAddress === "notice" ? "NOTICE" : "FREE";
+ const { data } = usePostListQuery({
+ clubId: clubId,
+ category: boardCategory,
+ page: 0,
+ size: 10,
+ });
const boardType = boardTypeAddress === "notice" ? "공지" : "자유";
const inPlusStyle: React.CSSProperties = {
width: "1.625rem",
@@ -30,19 +39,19 @@ const Board = () => {
- {testArr.map((item, index) => (
+ {data?.data.content.map((item, index) => (
))}
diff --git a/src/features/board/components/BoardDetail.css b/src/features/board/components/BoardDetail.css
index 952930c..fb4ec9e 100644
--- a/src/features/board/components/BoardDetail.css
+++ b/src/features/board/components/BoardDetail.css
@@ -49,3 +49,8 @@
display: fixed;
bottom: 0;
}
+
+.board__detail__comment {
+ padding-bottom: 5rem;
+ height: 100%;
+}
diff --git a/src/features/board/components/BoardDetail.tsx b/src/features/board/components/BoardDetail.tsx
index ed8afb0..4530484 100644
--- a/src/features/board/components/BoardDetail.tsx
+++ b/src/features/board/components/BoardDetail.tsx
@@ -1,20 +1,40 @@
-import { Comment, CommentInput } from "@/components/atoms/comment/index";
+import { CommentInput } from "@/components/atoms/comment/index";
import { Heart } from "@/components/atoms/heart/Heart";
import { Text } from "@/components/atoms/text";
import { ImageModal } from "@/components/molecules/ImageModal";
-// import useGetBoard from "@/hook/board/useGetBoardDetail";
+import { CommentList } from "@/components/molecules/commentList/CommentList";
+import { BoardHeader } from "@/components/organisms/Header";
+import { useCommentSort } from "@/hook/comment/useCommentSort";
+import useCommentsQuery from "@/hook/comment/useCommentsQuery";
import usePostDetailQuery from "@/hook/post/usePostDetailQuery";
+import {
+ useHeartCancleMutation,
+ useHeartMutation,
+} from "@/hook/post/useheartMutation";
import Image from "next/image";
+import { usePathname } from "next/navigation";
import { useState } from "react";
-import { BoardDetailArr, commentsArr } from "../constants/testArr/TestArr";
import "./BoardDetail.css";
export const BoardDetail = () => {
- const { data, isLoading } = usePostDetailQuery({ clubId: 4, postId: 9 });
- console.log(data);
+ const pathname = usePathname();
+ const pathProps = pathname.split("/").slice(1);
+ const postItem = {
+ clubId: parseInt(pathProps[0], 10),
+ postId: parseInt(pathProps[3], 10),
+ };
+ const { data, isLoading } = usePostDetailQuery(postItem);
+ const { mutate: isHaertMutate } = useHeartMutation(postItem);
+ const { mutate: isCancelHaertMutate } = useHeartCancleMutation(postItem);
const [isOpenModal, setIsOpenModal] = useState(false);
+ const [targetComment, setTargetComment] = useState
(
+ undefined
+ );
const [currentIndex, setCurrentIndex] = useState(-1);
+ const handleTargetComment = (commentId: number) => {
+ setTargetComment(commentId);
+ };
const handleIsHeart = () => {
- // 좋아요 요청 보내기
+ data && !data.data.isLiked ? isHaertMutate() : isCancelHaertMutate();
};
const handleOpenImg = (index: number) => {
// 사진 크게 보기
@@ -25,86 +45,127 @@ export const BoardDetail = () => {
// 사진 모달 닫기
setIsOpenModal(false);
};
+ const { data: commentList } = useCommentsQuery({
+ clubId: parseInt(pathProps[0], 10),
+ postId: parseInt(pathProps[3], 10),
+ size: 100,
+ page: 0,
+ });
+ const structuredComments = useCommentSort(commentList?.data.content);
+ // 로딩 중일 때
+ if (isLoading) {
+ return 로딩 중...
;
+ }
+
+ // data가 undefined인 경우
+ if (!data) {
+ return 데이터를 불러오는 중 오류가 발생했습니다.
;
+ }
+ console.log("dkdkdkdk", targetComment);
+ const DetailContent = data.data;
return (
<>
-
-
- {BoardDetailArr.title}
-
-
-
-
- {BoardDetailArr.writer.name}
-
+
+ <>
+
- {BoardDetailArr.date}
+ {DetailContent.postTitle}
-
-
-
-
- {BoardDetailArr.content}
+
+
+
+ {DetailContent.writerName}
+
+
+ {DetailContent.createdAt}
-
- {BoardDetailArr.contentImgs?.map((imgItem, index) => (
-
handleOpenImg(index)}
- >
-
-
- ))}
-
- {isOpenModal && (
-
- )}
+
+
+
+ {DetailContent.postContent}
+
+
+
+ {DetailContent.uploadImage?.map((imgItem, index) => (
+
handleOpenImg(index)}
+ >
+
+
+ ))}
+
+ {isOpenModal && (
+
+ )}
-
+
+
+
-
- 댓글 {BoardDetailArr.comment}
+
+ 댓글 {DetailContent.commentCount}
- {commentsArr.map((comment, index: number) => (
-
- ))}
+ {structuredComments &&
+ structuredComments
+ .slice()
+ .reverse()
+ .map((comment, index: number) => (
+
+ ))}
-
-
+
+ >
>
);
};
diff --git a/src/features/board/components/BoardItem.tsx b/src/features/board/components/BoardItem.tsx
index aee04b9..816645e 100644
--- a/src/features/board/components/BoardItem.tsx
+++ b/src/features/board/components/BoardItem.tsx
@@ -1,6 +1,5 @@
"use client";
-import testimg from "@/assets/images/chiikyaw.png";
import { Heart } from "@/components/atoms/heart/Heart";
import { Text } from "@/components/atoms/text";
import { ICONS } from "@/constants/images";
@@ -14,12 +13,12 @@ const BoardItem = ({
id,
title,
content,
- date,
- comment,
+ commentCount,
hearts,
contentImgs,
+ createdAt,
isHeart = false,
- writer: { profile = testimg, name },
+ writer: { profile, name },
}: BoardItemProps) => {
const router = useRouter();
const pathname = usePathname();
@@ -58,20 +57,26 @@ const BoardItem = ({
{/* 아래쪽 */}
-
+
{name}
- {date}
+ {createdAt}
-
+
- {comment}
+ {commentCount}
@@ -84,6 +89,8 @@ const BoardItem = ({
src={contentImgs[0]}
alt="contentImg"
className="home__content__meeting__right_img"
+ width={100}
+ height={100}
/>
)}
diff --git a/src/features/board/components/BoardItemProps.ts b/src/features/board/components/BoardItemProps.ts
index 06bcc18..b0cddee 100644
--- a/src/features/board/components/BoardItemProps.ts
+++ b/src/features/board/components/BoardItemProps.ts
@@ -1,18 +1,16 @@
-import { StaticImageData } from "next/image";
export interface BoardItemProps {
boardAddress?: string;
id: number;
title: string;
content: string;
- date: string;
- comment: number;
+ commentCount: number;
hearts: number;
- contentImgs?: StaticImageData[] | undefined;
-
+ contentImgs?: string[] | undefined;
isHeart: boolean;
writer: {
- profile: StaticImageData;
+ profile: string;
name: string;
};
+ createdAt: string;
}
diff --git a/src/features/board/components/BoardList.tsx b/src/features/board/components/BoardList.tsx
index 9c21105..4797072 100644
--- a/src/features/board/components/BoardList.tsx
+++ b/src/features/board/components/BoardList.tsx
@@ -1,12 +1,39 @@
+import usePostListQuery from "@/hook/post/usePostListQuery";
+import { usePathname } from "next/navigation";
import "./BoardList.css";
import BoardListBox from "./BoardListBox";
const BoardList = () => {
+ const pathname = usePathname();
+ const startedPath = pathname.split("/").slice(1)[0];
+ const clubId = parseInt(startedPath, 10);
+ const { data: noticeList } = usePostListQuery({
+ clubId: clubId,
+ category: "NOTICE",
+ page: 0,
+ size: 7,
+ });
+ const { data: freeList } = usePostListQuery({
+ clubId: clubId,
+ category: "FREE",
+ page: 0,
+ size: 7,
+ });
return (
);
};
diff --git a/src/features/board/components/BoardListBox.tsx b/src/features/board/components/BoardListBox.tsx
index 365d582..8e41caf 100644
--- a/src/features/board/components/BoardListBox.tsx
+++ b/src/features/board/components/BoardListBox.tsx
@@ -1,28 +1,33 @@
import { Text } from "@/components/atoms/text";
import { ICONS } from "@/constants/images";
+import { PostList } from "@/types/post";
import Image from "next/image";
-import { usePathname, useRouter } from "next/navigation";
-import { testArr } from "../constants/testArr/TestArr";
+import { useRouter } from "next/navigation";
import "./BoardListBox.css";
interface BoardListBoxProp {
- boardType: string;
+ clubId: number;
+ boardType: "공지" | "자유";
+ boardTypeAddress: "notice" | "free";
+ data: PostList[]|undefined;
}
interface BoardListItemProp {
id: number;
title: string;
}
-const BoardListBox = ({ boardType }: BoardListBoxProp) => {
- const boardTypeAddress = boardType === "공지" ? "notice" : "free";
+const BoardListBox = ({
+ clubId,
+ boardType,
+ boardTypeAddress,
+ data,
+}: BoardListBoxProp) => {
const router = useRouter();
- const pathname = usePathname();
- const startedPath = pathname.split("/").slice(1)[0];
const handleRouteBoard = (boardTypeAddress: string) => {
- router.push(`/${startedPath}/board/${boardTypeAddress}`);
+ router.push(`/${clubId}/board/${boardTypeAddress}`);
};
const BoardListItem = ({ id, title }: BoardListItemProp) => {
const handleRouteBoardDetail = (id: number) => {
- router.push(`/${startedPath}/board/${boardTypeAddress}/${id}`);
+ router.push(`/${clubId}/board/${boardTypeAddress}/${id}`);
};
return (
{
- {testArr.slice(0, 7).map((item, index) => (
-
+ {data?.map((item, index) => (
+
))}
diff --git a/src/features/home/SetHome.tsx b/src/features/home/SetHome.tsx
index 51b586f..f9d9120 100644
--- a/src/features/home/SetHome.tsx
+++ b/src/features/home/SetHome.tsx
@@ -19,9 +19,11 @@ export const ScheduleContext = createContext<{
const SetHome = () => {
const { value, setValue, filteredData, isLoading, mark } = useSchedule({
clubId: 1,
- q: "",
- sDate: moment().startOf('month').format("YYYY-MM-DD"),
- eDate: moment().endOf('month').format("YYYY-MM-DD")
+ keyword: "",
+ startDate: moment().startOf('month').format("YYYY-MM-DD"),
+ endDate: moment().endOf('month').format("YYYY-MM-DD"),
+ page: 0,
+ size: 20,
});
console.log(filteredData);
diff --git a/src/features/home/calendar/SetCalendar.tsx b/src/features/home/calendar/SetCalendar.tsx
index 55ad1b2..4138c5d 100644
--- a/src/features/home/calendar/SetCalendar.tsx
+++ b/src/features/home/calendar/SetCalendar.tsx
@@ -1,29 +1,36 @@
"use client";
import useSchedule from "@/hook/schedule/useSchedule";
-import moment from "moment";
-import { useSearchParams } from "next/navigation";
import CalendarList from "./components/CalendarList";
import { CalendarListHeader } from "./components/CalendarListHeader";
const SetCalendar = () => {
- const params = useSearchParams();
- const { data: scheduleData, refetchSchedule, isLoading, mark } = useSchedule({
+ const { data: scheduleData, refetchPeriodSchedule, refetchKeywordSchedule, isLoading, mark } = useSchedule({
clubId: 1,
- q: "",
- sDate: moment(params.get('month'), "YYYY-MM").startOf('month').format("YYYY-MM-DD"),
- eDate: moment(params.get('month'), "YYYY-MM").endOf('month').format("YYYY-MM-DD")
+ keyword: "",
+ startDate: "",
+ endDate: "",
+ page: 0,
+ size: 20,
});
return (
<>
- {!scheduleData ? (
-
loading...
- ):
- (
-
-
-
)
- }
+
+
+ {
+ isLoading ? (
+ <>>
+ ) : (
+
+ )
+ }
+
>
)
};
diff --git a/src/features/home/calendar/components/CalendarDetailContent.tsx b/src/features/home/calendar/components/CalendarDetailContent.tsx
index 9ed0bb2..3e6e884 100644
--- a/src/features/home/calendar/components/CalendarDetailContent.tsx
+++ b/src/features/home/calendar/components/CalendarDetailContent.tsx
@@ -8,7 +8,6 @@ interface CalendarDetailContentProps {
}
const CalendarDetailContent = ({ detailData } : CalendarDetailContentProps) => {
- console.log(detailData);
const renderDetailBox = (label: string, value: string | undefined) => (
diff --git a/src/features/home/calendar/components/CalendarDetailHeader.tsx b/src/features/home/calendar/components/CalendarDetailHeader.tsx
index df1bd99..ae2625f 100644
--- a/src/features/home/calendar/components/CalendarDetailHeader.tsx
+++ b/src/features/home/calendar/components/CalendarDetailHeader.tsx
@@ -10,17 +10,6 @@ interface CalendarDetailContentProps {
}
const CalendarDetailHeader = ({detailData}: CalendarDetailContentProps) => {
- const dateDetail =
- {
- id: 1,
- time: new Date(),
- user: "문해빈",
- title: "와이어 프레임 작성 회의",
- location: "커피빈 홍대입구점",
- content: "유저 플로우 기반으로 와이어프레임 작성하겠습니다. 테블릿 PC 지참해주세요 :) 출석은 정시에 가차없이 진행할 예정입니다. 지각 시에는 벌금 6000만원 있으니 참고하시어 늦지 마시길 ~ 모두 이따 봅시다",
- attendance: 0, // 미출석
- }
-
return (
(detailData && (
diff --git a/src/features/home/calendar/components/CalendarFilter.tsx b/src/features/home/calendar/components/CalendarFilter.tsx
index 6a47339..be2ece4 100644
--- a/src/features/home/calendar/components/CalendarFilter.tsx
+++ b/src/features/home/calendar/components/CalendarFilter.tsx
@@ -2,15 +2,19 @@ import { Text } from "@/components/atoms/text";
import { BottomSheet } from "@/components/organisms/BottomSheet/BottomSheet";
import { ICONS } from "@/constants/images";
import { COLORS } from "@/styles";
+import { ScheduleDate } from "@/types/schedule";
import Image from "next/image";
import { CALENDAR_FILTER_BTN } from "../constants/const";
import { useCalendarFilter } from "./CalendarFilterProvider";
-import { CalendarListHeaderProps } from "./CalendarListHeader";
import { CalendarPeriod } from "./CalendarPeriod";
+export interface CalendarFilterProps {
+ refetchPeriodSchedule: ({ startDate, endDate }: ScheduleDate) => void;
+}
+
export const CalendarFilter = ({
- refetchSchedule
-}: CalendarListHeaderProps) => {
+ refetchPeriodSchedule
+}: CalendarFilterProps) => {
const {openFloating, setOpenFloating, isPeriod, period} = useCalendarFilter();
return(
@@ -55,7 +59,7 @@ export const CalendarFilter = ({
setOpenFloating={setOpenFloating}
>
)}
diff --git a/src/features/home/calendar/components/CalendarFilterProvider.tsx b/src/features/home/calendar/components/CalendarFilterProvider.tsx
index c483358..71a5d08 100644
--- a/src/features/home/calendar/components/CalendarFilterProvider.tsx
+++ b/src/features/home/calendar/components/CalendarFilterProvider.tsx
@@ -32,10 +32,10 @@ interface CalendarFilterProviderProps {
}
export const CalendarFilterProvider = ({ children }: CalendarFilterProviderProps) => {
- const [openFloating, setOpenFloating] = useState(false);
- const [selectedIdx, setSelectedIdx] = useState(0);
- const [isPeriod, setIsPeriod] = useState(false);
- const [period, setPeriod] = useState
({
+ const [openFloating, setOpenFloating] = useState(false); // 바텀시트 오픈 여부
+ const [selectedIdx, setSelectedIdx] = useState(0); // 설정한 기간 idx
+ const [isPeriod, setIsPeriod] = useState(false); // 기간 설정 여부
+ const [period, setPeriod] = useState({ // 설정한 기간
startDate: moment(new Date()).format('YYYY-MM-DD'),
endDate: moment(new Date()).format('YYYY-MM-DD')
});
diff --git a/src/features/home/calendar/components/CalendarListHeader.tsx b/src/features/home/calendar/components/CalendarListHeader.tsx
index 9eea510..ebd9120 100644
--- a/src/features/home/calendar/components/CalendarListHeader.tsx
+++ b/src/features/home/calendar/components/CalendarListHeader.tsx
@@ -1,21 +1,25 @@
import { Search } from "@/components/atoms/search";
-import { FetchScheduleParams } from "@/types/schedule";
+import { ScheduleDate, ScheduleKeyword } from "@/types/schedule";
import { CalendarFilter } from "./CalendarFilter";
import { CalendarFilterProvider } from "./CalendarFilterProvider";
export interface CalendarListHeaderProps {
- refetchSchedule: (params: FetchScheduleParams) => void;
+ refetchPeriodSchedule: ({ startDate, endDate }: ScheduleDate) => void;
+ refetchKeywordSchedule: ({ keyword }: ScheduleKeyword) => void;
}
export const CalendarListHeader = ({
- refetchSchedule
+ refetchPeriodSchedule,
+ refetchKeywordSchedule
}: CalendarListHeaderProps) => {
return(
-
+
diff --git a/src/features/home/calendar/components/CalendarPeriod.tsx b/src/features/home/calendar/components/CalendarPeriod.tsx
index 26b1f9d..94baf35 100644
--- a/src/features/home/calendar/components/CalendarPeriod.tsx
+++ b/src/features/home/calendar/components/CalendarPeriod.tsx
@@ -4,13 +4,13 @@ import { Text } from "@/components/atoms/text";
import moment from "moment";
import { useState } from "react";
import { CALENDAR_PERIOD_BTN, CALENDAR_PERIOD_TXT, CALENDAR_PERIOD_TXT_LIST } from "../constants/const";
+import { CalendarFilterProps } from "./CalendarFilter";
import { useCalendarFilter } from "./CalendarFilterProvider";
-import { CalendarListHeaderProps } from "./CalendarListHeader";
export const CalendarPeriod = ({
- refetchSchedule
-}: CalendarListHeaderProps) => {
- const { setOpenFloating, selectedIdx, setSelectedIdx, setIsPeriod, period, setPeriod } = useCalendarFilter();
+ refetchPeriodSchedule
+}: CalendarFilterProps) => {
+ const { setOpenFloating, selectedIdx, setSelectedIdx, isPeriod, setIsPeriod, period, setPeriod } = useCalendarFilter();
const [tmpPeriod, setTmpPeriod] = useState({
startDate: period.startDate,
endDate: period.endDate
@@ -20,10 +20,23 @@ export const CalendarPeriod = ({
setSelectedIdx(0);
};
+ // 기간별 일정 refetch
+ const refetchNewSchedule = ({ newSDate, newEDate }: {
+ newSDate: string;
+ newEDate: string;
+ }) => {
+ refetchPeriodSchedule && refetchPeriodSchedule({
+ startDate: newSDate,
+ endDate: newEDate
+ });
+ }
+
const handlePeriod = () => {
if(selectedIdx === 0){
+ refetchNewSchedule({ newSDate: "", newEDate: "" });
setIsPeriod(false);
} else {
+ setIsPeriod(true); // 기간 설정했는지 여부
let newSDate = period.startDate;
let newEDate = period.endDate;
switch(selectedIdx) {
@@ -44,17 +57,22 @@ export const CalendarPeriod = ({
setPeriod(tmpPeriod);
break;
}
- refetchSchedule({
- clubId: 1,
- q: "",
- sDate: newSDate,
- eDate: newEDate
- });
- setIsPeriod(true);
+ refetchNewSchedule({ newSDate: newSDate, newEDate: newEDate });
+ setPeriod({
+ startDate: newSDate,
+ endDate: newEDate
+ }); // 설정한 기간
+ setIsPeriod(true); // 기간 설정했는지 여부
}
setOpenFloating(false); // 바텀시트 닫기
};
+ // useEffect(() => {
+ // if (isPeriod) {
+ // refetchNewSchedule({ newSDate: period.startDate, newEDate: period.endDate });
+ // }
+ // }, [period]);
+
return(
diff --git a/src/features/home/components/Home.css b/src/features/home/components/Home.css
index 306929a..a9984c6 100644
--- a/src/features/home/components/Home.css
+++ b/src/features/home/components/Home.css
@@ -23,7 +23,12 @@
margin-bottom: 1rem;
}
-.homeDateWrapper__header span {
+.homeDateWrapper__header::before {
+ width: 0px !important;
+ height: 0px !important;
+}
+
+.homeDateWrapper__header-btn {
cursor: pointer;
}
diff --git a/src/features/home/components/HomeDateWrapper.tsx b/src/features/home/components/HomeDateWrapper.tsx
index c06bda8..8d67343 100644
--- a/src/features/home/components/HomeDateWrapper.tsx
+++ b/src/features/home/components/HomeDateWrapper.tsx
@@ -1,5 +1,4 @@
"use client";
-import moment from "moment";
import React, { useContext } from "react";
import "./Home.css";
@@ -28,11 +27,12 @@ const HomeDateWrapper = ({ dateList, isLoading }: {
fontWeight="700"
>{formatDateKor(value)}
더보기
diff --git a/src/features/home/components/HomeHeader.tsx b/src/features/home/components/HomeHeader.tsx
index b0d0c69..1608e29 100644
--- a/src/features/home/components/HomeHeader.tsx
+++ b/src/features/home/components/HomeHeader.tsx
@@ -1,5 +1,4 @@
import { HomeCalendar } from "@/components/atoms/calendar";
-import { Search } from "@/components/atoms/search";
import { useContext } from 'react';
import { ScheduleContext } from '../SetHome'; // Adjust the path as needed
import "./Home.css";
@@ -10,7 +9,7 @@ const HomeHeader = ({ mark }: {
const { value, onChange } = useContext(ScheduleContext);
return (
-
+ {/*
*/}
console.log(date)}
value={value}
diff --git a/src/features/info/board/like/InfoBoardLike.tsx b/src/features/info/board/like/InfoBoardLike.tsx
new file mode 100644
index 0000000..17f91e5
--- /dev/null
+++ b/src/features/info/board/like/InfoBoardLike.tsx
@@ -0,0 +1,52 @@
+"use client";
+import { HistoryHeader } from "@/components/organisms/Header";
+import { Nav } from "@/components/organisms/Nav";
+import { IMAGES } from "@/constants/images";
+import BoardItem from "@/features/board/components/BoardItem";
+import useMyPostLikeQuery from "@/hook/info/useMyPostLikeQuery";
+
+import "./components/BoardLike.css";
+
+export const InfoBoardLike = () => {
+ const { data: boardInfo } = useMyPostLikeQuery({
+ clubId: 7,
+ userId: 6,
+ category: "FREE",
+ page: 0,
+ size: 10,
+ });
+ console.log(boardInfo);
+
+ return(
+ <>
+
+ {/* TODO: skeleton UI 적용 */}
+ {
+ !boardInfo || !boardInfo.data ?
+ Loading...
:
+ (
+
+ {boardInfo?.data?.content?.map((item: any) => (
+
+ ))}
+
+ )
+ }
+
+ >
+ )
+};
\ No newline at end of file
diff --git a/src/features/info/board/like/components/BoardLike.css b/src/features/info/board/like/components/BoardLike.css
new file mode 100644
index 0000000..e8c3f4e
--- /dev/null
+++ b/src/features/info/board/like/components/BoardLike.css
@@ -0,0 +1,5 @@
+.infoBoard {
+ width: 90vw;
+ margin: 1rem auto;
+ padding-top: 4.5rem;
+}
\ No newline at end of file
diff --git a/src/features/info/board/like/constants/const.ts b/src/features/info/board/like/constants/const.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/features/info/board/like/constants/index.ts b/src/features/info/board/like/constants/index.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/features/info/board/write/InfoBoardWrite.tsx b/src/features/info/board/write/InfoBoardWrite.tsx
index fef1a1e..d81891e 100644
--- a/src/features/info/board/write/InfoBoardWrite.tsx
+++ b/src/features/info/board/write/InfoBoardWrite.tsx
@@ -1,33 +1,50 @@
+"use client";
import { HistoryHeader } from "@/components/organisms/Header";
import { Nav } from "@/components/organisms/Nav";
import BoardItem from "@/features/board/components/BoardItem";
-import { testArr } from "@/features/board/constants/testArr/TestArr";
+import useMyPostQuery from "@/hook/info/useMyPostQuery";
+import { IMAGES } from "@/constants/images";
import "./components/BoardWrite.css";
export const InfoBoardWrite = () => {
+ const { data: boardInfo } = useMyPostQuery({
+ clubId: 7,
+ category: "FREE",
+ page: 0,
+ size: 10,
+ });
+ console.log(boardInfo);
+
return(
<>
-
- {testArr.map((item, index) => (
-
- ))}
-
+ {/* TODO: skeleton UI 적용 */}
+ {
+ !boardInfo || !boardInfo.data ?
+ Loading...
:
+ (
+
+ {boardInfo?.data?.content?.map((item: any) => (
+
+ ))}
+
+ )
+ }
>
)
diff --git a/src/features/info/club/MemberClubInfo.tsx b/src/features/info/club/MemberClubInfo.tsx
index 49dcd8c..62aef51 100644
--- a/src/features/info/club/MemberClubInfo.tsx
+++ b/src/features/info/club/MemberClubInfo.tsx
@@ -4,9 +4,9 @@ import { HistoryHeader } from "@/components/organisms/Header";
import { Nav } from "@/components/organisms/Nav";
import { useClubsInfoQuery } from "@/hook/club/useClubsInfoQuery";
import { ClubInfo } from "./components/ClubInfo";
-import "./components/ClubInfo.css";
import { ClubProfile } from "./components/ClubProfile";
+import "./components/ClubInfo.css";
export const MemberClubInfo = () => {
const params = {
clubId : 1
diff --git a/src/features/manager/attendance/components/CurrentAttendance.tsx b/src/features/manager/attendance/components/CurrentAttendance.tsx
index 77ed270..59c019a 100644
--- a/src/features/manager/attendance/components/CurrentAttendance.tsx
+++ b/src/features/manager/attendance/components/CurrentAttendance.tsx
@@ -18,9 +18,9 @@ const CurrentAttendance: React.FC = ({
attendanceUpdated,
onAttendanceUpdate,
}) => {
- const { data, isError, refetch } = useAttendanceListQuery({
- clubId: 1,
- });
+ const clubId = 1;
+ const scheduleId = 13;
+ const { data, isError, refetch } = useAttendanceListQuery(clubId);
const [selectedAttendance, setSelectedAttendance] =
useState(null);
diff --git a/src/features/manager/attendance/components/TodaySchedule.tsx b/src/features/manager/attendance/components/TodaySchedule.tsx
index 3878d3c..54dcb4d 100644
--- a/src/features/manager/attendance/components/TodaySchedule.tsx
+++ b/src/features/manager/attendance/components/TodaySchedule.tsx
@@ -1,14 +1,15 @@
-"use client"; // 클라이언트 컴포넌트로 지정
+"use client";
-import React, { useState, useEffect } from "react";
-import { ATTENDANCE_MODAL, TODAY_SCHEDULE_TITLE } from "../constants/const";
-import AttendanceItem from "@/components/molecules/attendanceItem/AttendanceItem";
import { Text } from "@/components/atoms/text";
-import "./Attendance.css";
+import AttendanceItem from "@/components/molecules/attendanceItem/AttendanceItem";
+import { Modal } from "@/components/organisms/Modal/Modal";
+import { useModalContext } from "@/components/organisms/Modal/ModalProvider";
import { useAttendanceStartQuery } from "@/hook/attendance/manager/useAttendanceStartQuery";
import { useTodayScheduleListQuery } from "@/hook/attendance/manager/useTodayScheduleListQuery";
import { ScheduleContent } from "@/types/schedule";
-import { Modal } from "@/components/organisms/Modal/Modal";
+import React, { useEffect, useState } from "react";
+import { ATTENDANCE_MODAL, TODAY_SCHEDULE_TITLE } from "../constants/const";
+import "./Attendance.css";
interface TodayScheduleProps {
attendanceUpdated: boolean;
@@ -22,47 +23,71 @@ const TodaySchedule: React.FC = ({
const clubId = 1;
const [selectedSchedule, setSelectedSchedule] =
useState(null);
+ const { isOpen, openModal, closeModal } = useModalContext();
const [startAttendance, setStartAttendance] = useState(false);
- const [isModalOpen, setIsModalOpen] = useState(false);
+
+ const getCurrentDate = () => {
+ const today = new Date();
+ const year = today.getFullYear();
+ const month = String(today.getMonth() + 1).padStart(2, "0");
+ const day = String(today.getDate()).padStart(2, "0");
+ return `${year}-${month}-${day}`;
+ };
const {
data: todayScheduleData,
- isLoading: isTodayScheduleLoading,
isError: isTodayScheduleError,
refetch: refetchTodaySchedule,
} = useTodayScheduleListQuery({
clubId: clubId,
- sDate: "2024-05-28",
- eDate: "2024-05-28",
+ startDate: getCurrentDate(),
+ endDate: getCurrentDate(),
+ page: 0,
+ size: 10,
});
- const { data: attendanceData, refetch: refetchAttendance } =
- useAttendanceStartQuery({
- clubId: clubId,
- scheduleId: selectedSchedule?.scheduleId || 0,
- });
-
- useEffect(() => {
- refetchTodaySchedule();
- }, [attendanceUpdated, refetchTodaySchedule]);
+ const { refetch: refetchAttendance } = useAttendanceStartQuery({
+ clubId: clubId,
+ scheduleId: selectedSchedule?.scheduleId || 0,
+ enabled: false,
+ });
const handleOpenModal = (schedule: ScheduleContent) => {
+ console.log("handleOpenModal called with schedule:", schedule); // 디버깅 로그 추가
if (schedule.attendanceStatus === "BEFORE") {
setSelectedSchedule(schedule);
- setIsModalOpen(true);
+ openModal();
+ console.log("Modal opened with schedule:", schedule); // 디버깅 로그 추가
}
};
const handleAttendanceStart = () => {
- setStartAttendance(true);
+ console.log("handleAttendanceStart called"); // 디버깅 로그 추가
+ if (selectedSchedule) {
+ setStartAttendance(true);
+ }
+ };
+
+ const handleRefetchAttendance = async () => {
+ try {
+ const { data } = await refetchAttendance();
+ console.log(data); // 여기서 응답 본문을 필요한 대로 처리할 수 있습니다
+ // 응답 데이터를 처리하기 위한 추가 로직
+ } catch (error) {
+ console.error("출석 데이터를 다시 가져오는 중 에러 발생:", error);
+ // 에러를 필요한 대로 처리
+ }
};
useEffect(() => {
if (startAttendance && selectedSchedule) {
refetchAttendance().then(() => {
+ onAttendanceUpdate();
+ refetchTodaySchedule();
+ handleRefetchAttendance();
+ closeModal();
setStartAttendance(false);
- onAttendanceUpdate(); // 상태 변경 함수 호출
- setIsModalOpen(false);
+ console.log("Attendance started and modal closed"); // 디버깅 로그 추가
});
}
}, [
@@ -70,6 +95,7 @@ const TodaySchedule: React.FC = ({
selectedSchedule,
refetchAttendance,
onAttendanceUpdate,
+ refetchTodaySchedule,
]);
if (isTodayScheduleError) {
@@ -114,20 +140,18 @@ const TodaySchedule: React.FC = ({
/>
))}
- {selectedSchedule && (
-
-
-
- {ATTENDANCE_MODAL.start}
-
-
-
-
- {ATTENDANCE_MODAL.yes}
-
-
-
- )}
+
+
+
+ {ATTENDANCE_MODAL.start}
+
+
+
+
+ {ATTENDANCE_MODAL.yes}
+
+
+
);
};
diff --git a/src/features/member/attendance/AttendanceListPage.tsx b/src/features/member/attendance/AttendanceListPage.tsx
index 2cce08c..c401ba3 100644
--- a/src/features/member/attendance/AttendanceListPage.tsx
+++ b/src/features/member/attendance/AttendanceListPage.tsx
@@ -1,13 +1,14 @@
import React from "react";
import { Nav } from "@/components/organisms/Nav";
import AttendanceList from "./components/AttendanceList";
+import { ToastContainer } from "react-toastify";
const AttendanceListPage: React.FC = () => {
return (
<>
- {/*
*/}
+
-
+ {/*
*/}
>
);
};
diff --git a/src/features/member/attendance/components/AttendanceList.tsx b/src/features/member/attendance/components/AttendanceList.tsx
index 48642d5..cc25025 100644
--- a/src/features/member/attendance/components/AttendanceList.tsx
+++ b/src/features/member/attendance/components/AttendanceList.tsx
@@ -9,10 +9,9 @@ import { useModalContext } from "@/components/organisms/Modal/ModalProvider";
import { ATTEND_BTN, ATTEND_MODAL } from "../constants/const";
import { CodeInput } from "@/components/atoms/input/CodeInput";
import { AttendanceListItem } from "@/types/attendance/types";
-import { useParams } from "next/navigation";
+import { useAttendanceReqMutation } from "@/hook/attendance/member/useAttendanceMutationReqQuery";
const AttendanceList: React.FC = () => {
- // const { id } = useParams<{ id: string }>();
const { isOpen, openModal, closeModal } = useModalContext();
const [codeValues, setCodeValues] = useState
(Array(3).fill(""));
const [isComplete, setIsComplete] = useState(false);
@@ -21,16 +20,21 @@ const AttendanceList: React.FC = () => {
const [selectedAttendance, setSelectedAttendance] =
useState(null);
- // useAttendanceListQuery 훅을 사용하여 데이터 불러오기
- const { data, isLoading, isError } = useAttendanceListQuery({
- clubId: 1,
- });
+ const clubId = 1;
+ const { data, isError } = useAttendanceListQuery(clubId);
console.log(data);
+ const { mutate: requestAttendance } = useAttendanceReqMutation({
+ clubId: clubId,
+ scheduleId: selectedAttendance?.scheduleId || 0,
+ });
+
const onSubmit = () => {
closeModal();
- if (isComplete) {
- const attendanceData = { attendanceNum: 0 }; // 실제 데이터를 사용하세요
+ if (isComplete && selectedAttendance) {
+ const attendanceNum = parseInt(codeValues.join(""));
+ const attendanceData = { attendanceNum };
+ requestAttendance(attendanceData);
}
};
@@ -61,10 +65,6 @@ const AttendanceList: React.FC = () => {
}
}, [codeValues]);
- if (isLoading) {
- return Loading...
;
- }
-
if (isError) {
return Error loading attendance list.
;
}
diff --git a/src/features/Login/Login.tsx b/src/features/user/Login/Login.tsx
similarity index 100%
rename from src/features/Login/Login.tsx
rename to src/features/user/Login/Login.tsx
diff --git a/src/features/Login/components/Login.css b/src/features/user/Login/components/Login.css
similarity index 100%
rename from src/features/Login/components/Login.css
rename to src/features/user/Login/components/Login.css
diff --git a/src/features/Login/components/LoginBtn.tsx b/src/features/user/Login/components/LoginBtn.tsx
similarity index 100%
rename from src/features/Login/components/LoginBtn.tsx
rename to src/features/user/Login/components/LoginBtn.tsx
diff --git a/src/features/Login/components/LoginTitle.tsx b/src/features/user/Login/components/LoginTitle.tsx
similarity index 100%
rename from src/features/Login/components/LoginTitle.tsx
rename to src/features/user/Login/components/LoginTitle.tsx
diff --git a/src/features/Login/constants/const.ts b/src/features/user/Login/constants/const.ts
similarity index 100%
rename from src/features/Login/constants/const.ts
rename to src/features/user/Login/constants/const.ts
diff --git a/src/features/user/club/SetupUserClub.tsx b/src/features/user/club/SetupUserClub.tsx
index 9e576eb..ff59e94 100644
--- a/src/features/user/club/SetupUserClub.tsx
+++ b/src/features/user/club/SetupUserClub.tsx
@@ -13,6 +13,18 @@ export default function SetupUserClub() {
const methods = useForm({
mode: "onChange",
+ defaultValues: {
+ clubIntro: "",
+ // clubLinks: "", 링크 추가 시 주석 해제
+ clubName: "",
+ contactMeans: "",
+ isPrivate: false,
+ namePolicy: "REAL_NAME",
+ profileImage: {
+ url: "",
+ imageFile: undefined
+ }
+ }
});
const { handleSubmit, control } = methods;
@@ -25,6 +37,7 @@ export default function SetupUserClub() {
};
const createClubMutation = useClubsMutation();
const submitSignup = (data: ClubFormData) => {
+ console.log(data);
createClubMutation.mutate(data);
};
diff --git a/src/features/user/club/components/FirstClubRegister.css b/src/features/user/club/components/FirstClubRegister.css
index 3ce00fe..1afcaa9 100644
--- a/src/features/user/club/components/FirstClubRegister.css
+++ b/src/features/user/club/components/FirstClubRegister.css
@@ -9,4 +9,5 @@
.register__content {
padding-top: 5rem;
+ width: 90%;
}
\ No newline at end of file
diff --git a/src/features/user/home/components/Home.css b/src/features/user/home/components/Home.css
index e276951..6905dcf 100644
--- a/src/features/user/home/components/Home.css
+++ b/src/features/user/home/components/Home.css
@@ -1,5 +1,5 @@
.home {
- height: calc(100vh - 5.5rem);
+ /* height: calc(100vh - 5.5rem); */
position: relative;
display: flex;
flex-direction: column;
diff --git a/src/features/user/home/components/Home.tsx b/src/features/user/home/components/Home.tsx
index 0e5ec7b..2540af0 100644
--- a/src/features/user/home/components/Home.tsx
+++ b/src/features/user/home/components/Home.tsx
@@ -67,7 +67,6 @@ const Home = () => {
) : (
<>
- {console.log("dkdk", requestedClubList.data)}
{/* 모임 */}
{requestedClubList?.data?.content &&
requestedClubList?.data?.content?.map((item, idx) => (
diff --git a/src/features/user/home/components/HomeRequestedModal.tsx b/src/features/user/home/components/HomeRequestedModal.tsx
index 22c6307..ba67794 100644
--- a/src/features/user/home/components/HomeRequestedModal.tsx
+++ b/src/features/user/home/components/HomeRequestedModal.tsx
@@ -24,7 +24,7 @@ const HomeRequestedModal = ({
return (
-
+
{title}
{date}
diff --git a/src/features/user/home/components/MeetingItem.css b/src/features/user/home/components/MeetingItem.css
index 5680025..07dd8bd 100644
--- a/src/features/user/home/components/MeetingItem.css
+++ b/src/features/user/home/components/MeetingItem.css
@@ -1,7 +1,7 @@
.home__content__meeting__box {
display: flex;
padding: 0.94rem 1rem 0.94rem 1.06rem;
- width: 100%;
+ width: 90%;
border-radius: 0.625rem;
background: #404040;
diff --git a/src/features/user/home/components/RequestedMeetingItem.tsx b/src/features/user/home/components/RequestedMeetingItem.tsx
index a2232ba..748f197 100644
--- a/src/features/user/home/components/RequestedMeetingItem.tsx
+++ b/src/features/user/home/components/RequestedMeetingItem.tsx
@@ -1,9 +1,12 @@
import { Text } from "@/components/atoms/text";
-import { useModalContext } from "@/components/organisms/Modal/ModalProvider";
+// import { useModalContext } from "@/components/organisms/Modal/ModalProvider";
import { useJoinCancelMutation } from "@/hook/clubJoin/useJoinCancelMutation";
+import { useJoinDeleteMutation } from "@/hook/clubJoin/useJoinDeleteMutation";
import { useJoinRejectedQuery } from "@/hook/clubJoin/useJoinRejectedQuery";
import useSwipeItemHandles from "@/hook/user/useSwipeItemHandles";
import { ApprovalStatus, RequestedJoinClubInfo } from "@/types/club";
+import { useState } from "react";
+import { HOME_JOIN_CANCLE } from "../constants/const";
import HomeRequestedModal from "./HomeRequestedModal";
import "./RequestedMeetingItem.css";
@@ -15,23 +18,25 @@ const RequestedMeetingItem = ({
updatedAt,
}: RequestedJoinClubInfo) => {
const isSwipe = status == ApprovalStatus.Rejected;
- const { isOpen, openModal, closeModal } = useModalContext();
+ const StateEqualRejectedOrCanceled =
+ status == ApprovalStatus.Cancel || status == ApprovalStatus.Rejected;
+ const [isOpen, setIsOpen] = useState(false);
+ const openModal = () => setIsOpen(true);
+ const closeModal = () => setIsOpen(false);
+
const { mutate: cancelMutate } = useJoinCancelMutation(clubJoinRequestId);
- const { data: rejectedData, isLoading } =
- useJoinRejectedQuery(clubJoinRequestId, status);
+ const { mutate: deleteMutate } = useJoinDeleteMutation(clubJoinRequestId);
+ const { data: rejectedData, isLoading } = useJoinRejectedQuery(
+ clubJoinRequestId,
+ status
+ );
- const rejectedDataText = rejectedData?.rejectionReason;
+ const rejectedDataText =
+ rejectedData?.data.rejectionReason || HOME_JOIN_CANCLE.content;
const handleOpenModal = () => {
openModal();
};
- const requestData = {
- title: clubName,
- date: updatedAt,
- content: rejectedDataText || "",
- // : HOME_JOIN_CANCLE.content,
- };
-
const {
handleTouchStart,
handleMouseDown,
@@ -45,10 +50,12 @@ const RequestedMeetingItem = ({
return (
+
{status == ApprovalStatus.Approved
? "승인"
: status == ApprovalStatus.Waiting
? "승인 대기 중"
- : "거절됨"}
+ : status == ApprovalStatus.Rejected
+ ? "거절됨"
+ : "취소됨"}
@@ -106,7 +116,9 @@ const RequestedMeetingItem = ({
title={clubName}
date={updatedAt}
content={rejectedDataText || ""}
- cancelMutate={cancelMutate}
+ cancelMutate={
+ status == ApprovalStatus.Waiting ? cancelMutate : deleteMutate
+ }
/>
);
diff --git a/src/features/user/joinClub/components/EnterInvitationCode.tsx b/src/features/user/joinClub/components/EnterInvitationCode.tsx
index b78a69d..848aee2 100644
--- a/src/features/user/joinClub/components/EnterInvitationCode.tsx
+++ b/src/features/user/joinClub/components/EnterInvitationCode.tsx
@@ -1,23 +1,26 @@
"use client"; // 클라이언트 컴포넌트로 지정
+import { Button } from "@/components/atoms/button";
import { CodeInput } from "@/components/atoms/input/CodeInput";
import { Text } from "@/components/atoms/text";
-import "./EnterInvitationCode.css";
-import { Button } from "@/components/atoms/button";
import { HistoryHeader } from "@/components/organisms/Header";
-import Image from "next/image";
import { IMAGES } from "@/constants/images";
+import { fetchJoinClub } from "@/hook/clubJoin/useJoinClubQuery";
+import Image from "next/image";
+import { useRouter } from "next/navigation";
+import React, { useEffect, useRef, useState } from "react";
import {
ENTER_INVITATION_CODE,
JOIN_BTN,
RECEIVE_INVITATION_CODE,
} from "../constants/const";
-import React, { useRef, useState, useEffect } from "react";
+import "./EnterInvitationCode.css";
const EnterInvitationCode = () => {
const [codeValues, setCodeValues] = useState(Array(6).fill(""));
const [isComplete, setIsComplete] = useState(false);
const inputRefs = useRef<(HTMLInputElement | null)[]>([]);
+ const router = useRouter();
const setFocus = (index: number) => {
if (index >= 0 && index < inputRefs.current.length) {
@@ -46,6 +49,16 @@ const EnterInvitationCode = () => {
}
}, [codeValues]);
+ const onSubmit = async () => {
+ if (isComplete) {
+ const {
+ data: clubInfo,
+ } = await fetchJoinClub(codeValues.join(''));
+ console.log(clubInfo);
+ router.push(`/user/club/join/${clubInfo.clubId}`);
+ }
+ }
+
return (
@@ -81,9 +94,7 @@ const EnterInvitationCode = () => {
diff --git a/src/features/user/joinClub/constants/const.ts b/src/features/user/joinClub/constants/const.ts
index 33413a4..93e3979 100644
--- a/src/features/user/joinClub/constants/const.ts
+++ b/src/features/user/joinClub/constants/const.ts
@@ -1,4 +1,4 @@
export const ENTER_INVITATION_CODE = "초대 코드 입력";
export const RECEIVE_INVITATION_CODE =
"관리자에게 받은 초대코드 6자리를 입력해주세요";
-export const JOIN_BTN = "초대코드로 가입하기";
+export const JOIN_BTN = "초대코드로 모임 조회하기";
diff --git a/src/features/user/profile/components/AccountInfo.tsx b/src/features/user/profile/components/AccountInfo.tsx
index 9cd43ed..2e8ada3 100644
--- a/src/features/user/profile/components/AccountInfo.tsx
+++ b/src/features/user/profile/components/AccountInfo.tsx
@@ -5,12 +5,12 @@ import { ACCOUNT_INFO } from "../constants/const";
import { NAME } from "@/constants/const";
import { useRouter } from "next/navigation";
import React from "react";
+import { useGetUserInfoQuery } from "@/hook/user/useGetUserInfoQuery";
const AccountInfo: React.FC = () => {
const router = useRouter();
- const name = "홍길동";
- const email = "whatshu@gamil.com";
- const phoneNum = "010-1234-5678";
+ const { data } = useGetUserInfoQuery();
+ const userInfo = data?.data;
return (
@@ -31,9 +31,9 @@ const AccountInfo: React.FC = () => {
{ACCOUNT_INFO.phoneNum}
-
{name}
-
{email}
-
{phoneNum}
+
{userInfo?.userName}
+
{userInfo?.userEmail}
+
{userInfo?.userPhone}
diff --git a/src/features/user/profile/components/EditProfile.tsx b/src/features/user/profile/components/EditProfile.tsx
index 20bb6bb..c2deea1 100644
--- a/src/features/user/profile/components/EditProfile.tsx
+++ b/src/features/user/profile/components/EditProfile.tsx
@@ -4,31 +4,46 @@ import { Button } from "@/components/atoms/button";
import { InputBox } from "@/components/molecules/inputBox";
import { Wrapper } from "@/components/organisms/Wrapper";
import { useRouter } from "next/navigation";
-import React from "react";
+import React, { useEffect } from "react";
import { useForm, SubmitHandler } from "react-hook-form";
import {
EDIT_ACCOUNT_INFO_BTN,
EDIT_ACCOUNT_INFO_INPUT_ARR,
} from "../constants/const";
-
-interface FormData {
- userName: string;
- userEmail: string;
- userMobile: string;
-}
+import { signUpInfo } from "@/types/user/types";
+import { useGetUserInfoQuery } from "@/hook/user/useGetUserInfoQuery";
+import { useModificationUserInfoMutation } from "@/hook/user/useModificationUserInfoMutation";
+import { useQueryClient } from "@tanstack/react-query";
const EditProfile: React.FC = () => {
const router = useRouter();
- const methods = useForm({
+ const methods = useForm({
mode: "onChange",
});
-
- const { handleSubmit, control } = methods;
-
- const submitOnboarding: SubmitHandler = (data) => {
- console.log(data);
+ const { handleSubmit, control, setValue } = methods;
+ const { data: userInfo } = useGetUserInfoQuery();
+ const mutation = useModificationUserInfoMutation();
+ const queryClient = useQueryClient();
+ const submitOnboarding: SubmitHandler = (data) => {
+ mutation.mutate(data, {
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ["userInfo"] });
+ router.push("/user/profile");
+ },
+ onError: (error) => {
+ console.error("Error updating user info:", error);
+ },
+ });
};
+ useEffect(() => {
+ if (userInfo) {
+ setValue("userName", userInfo.data.userName);
+ setValue("userPhone", userInfo.data.userPhone);
+ setValue("userEmail", userInfo.data.userEmail);
+ }
+ });
+
return (
-
+
);
diff --git a/src/features/user/profile/constants/const.ts b/src/features/user/profile/constants/const.ts
index 749016d..abfac5b 100644
--- a/src/features/user/profile/constants/const.ts
+++ b/src/features/user/profile/constants/const.ts
@@ -14,29 +14,29 @@ export const ACCOUNT_SETTING = {
export const EDIT_ACCOUNT_INFO = "계정 정보 수정";
export const EDIT_ACCOUNT_INFO_INPUT_ARR = [
- {
- title: "이름",
- type: "input",
- essential: true,
- name: "userName"
- },
- {
- title: "이메일",
- type: "input",
- essential: true,
- name: "userEmail"
- },
- {
- title: "휴대폰 번호",
- type: "btnInput",
- essential: true,
- name: "userMobile"
- }
-]
+ {
+ title: "이름",
+ type: "input",
+ essential: true,
+ name: "userName",
+ },
+ {
+ title: "이메일",
+ type: "input",
+ essential: true,
+ name: "userEmail",
+ },
+ {
+ title: "휴대폰 번호",
+ type: "btnInput",
+ essential: true,
+ name: "userPhone",
+ },
+];
export const EDIT_ACCOUNT_INFO_BTN = {
getNum: "인증번호 받기",
checkNum: "인증번호 확인",
retryNum: "재전송",
- complete: "수정 완료"
+ complete: "수정 완료",
};
diff --git a/src/hook/attendance/manager/useAttendanceEndMutationQuery.ts b/src/hook/attendance/manager/useAttendanceEndMutationQuery.ts
index ef9c8a7..038f7ec 100644
--- a/src/hook/attendance/manager/useAttendanceEndMutationQuery.ts
+++ b/src/hook/attendance/manager/useAttendanceEndMutationQuery.ts
@@ -1,11 +1,11 @@
import { http } from "@/apis/http";
-import { AttendanceInfo } from "@/types/attendance/types";
+import { ScheduleDetailProp } from "@/types/schedule";
import { useMutation } from "@tanstack/react-query";
export const useAttendanceEndMutationQuery = ({
clubId,
scheduleId,
-}: Omit
) => {
+}: ScheduleDetailProp) => {
return useMutation({
mutationFn: (data: string) =>
http.post(`/${clubId}/schedules/${scheduleId}/attendance-end`, data),
diff --git a/src/hook/attendance/manager/useAttendanceStartQuery.ts b/src/hook/attendance/manager/useAttendanceStartQuery.ts
index 280fd3b..72f91a9 100644
--- a/src/hook/attendance/manager/useAttendanceStartQuery.ts
+++ b/src/hook/attendance/manager/useAttendanceStartQuery.ts
@@ -6,13 +6,15 @@ import { useQuery } from "@tanstack/react-query";
export const useAttendanceStartQuery = ({
clubId,
scheduleId,
-}: ScheduleDetailProp) => {
+ enabled = true,
+}: ScheduleDetailProp & { enabled?: boolean }) => {
return useQuery({
queryKey: [`attendanceStart`, { clubId, scheduleId }],
queryFn: () =>
- http.get(
- `/${clubId}/schedules/${scheduleId}/attendance-start`,
+ http.post(
+ `/clubs/${clubId}/schedules/${scheduleId}/attendance-start`,
{ headers: { accept: "*/*" } }
),
+ enabled,
});
};
diff --git a/src/hook/attendance/manager/useTodayScheduleListQuery.ts b/src/hook/attendance/manager/useTodayScheduleListQuery.ts
index 43d08cc..fc649dd 100644
--- a/src/hook/attendance/manager/useTodayScheduleListQuery.ts
+++ b/src/hook/attendance/manager/useTodayScheduleListQuery.ts
@@ -1,18 +1,24 @@
import { http } from "@/apis/http";
import { CommonRes } from "@/types";
-import { AttendanceSchedule, TodayScheduleItem } from "@/types/attendance/types";
+import {
+ AttendanceSchedule,
+ TodayScheduleItem,
+} from "@/types/attendance/types";
import { useQuery } from "@tanstack/react-query";
export const useTodayScheduleListQuery = ({
clubId,
- sDate,
- eDate,
+ startDate,
+ endDate,
+ page,
+ size,
+ sort="",
}: TodayScheduleItem) => {
return useQuery>({
- queryKey: ["todayScheduleList", clubId, sDate, eDate],
+ queryKey: ["todayScheduleList", clubId, startDate, endDate],
queryFn: async () => {
const response = await http.get>(
- `/clubs/${clubId}/schedules?sDate=${sDate}&eDate=${eDate}`
+ `/clubs/${clubId}/schedules?startDate=${startDate}&endDate=${endDate}&page=${page}&size=${size}`
);
return response;
},
diff --git a/src/hook/attendance/member/useAttendanceMutationQuery.ts b/src/hook/attendance/member/useAttendanceMutationQuery.ts
deleted file mode 100644
index 8a83109..0000000
--- a/src/hook/attendance/member/useAttendanceMutationQuery.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-// import { http } from "@/apis/http";
-// import { useMutation } from "@tanstack/react-query";
-// import { AttendanceData, AttendanceProp } from "@/types/attendance/types";
-
-// export const useAttendanceMutationQuery = ({
-// clubId,
-// scheduleId,
-// memberId,
-// }: AttendanceProp) => {
-// return useMutation({
-// mutationFn: (data: AttendanceData) =>
-// http.post(
-// `/api/${clubId}/schedules/${scheduleId}/attendance/${memberId}`,
-// data
-// ),
-// onSuccess: (data) => {
-// console.log("Attendance updated:", data);
-// },
-// onError: (error) => {
-// console.error("Error updating attendance:", error);
-// },
-// });
-// };
diff --git a/src/hook/attendance/member/useAttendanceMutationReqQuery.ts b/src/hook/attendance/member/useAttendanceMutationReqQuery.ts
new file mode 100644
index 0000000..7c38ed1
--- /dev/null
+++ b/src/hook/attendance/member/useAttendanceMutationReqQuery.ts
@@ -0,0 +1,17 @@
+import { http } from "@/apis/http";
+import { AttendanceReqData } from "@/types/attendance/types";
+import { ScheduleDetailProp } from "@/types/schedule";
+import { useMutation } from "@tanstack/react-query";
+
+export const useAttendanceReqMutation = ({
+ clubId,
+ scheduleId,
+}: ScheduleDetailProp) => {
+ return useMutation({
+ mutationFn: (data: AttendanceReqData) =>
+ http.post(`/clubs/${clubId}/schedules/${scheduleId}/attendance/`, data),
+ onSuccess: (data) => {
+ console.log(data);
+ },
+ });
+};
diff --git a/src/hook/attendance/useAttendanceListQuery.ts b/src/hook/attendance/useAttendanceListQuery.ts
index c777d19..46b6186 100644
--- a/src/hook/attendance/useAttendanceListQuery.ts
+++ b/src/hook/attendance/useAttendanceListQuery.ts
@@ -1,20 +1,14 @@
import { http } from "@/apis/http";
import { CommonNoPageRes } from "@/types";
import { GetAttendanceListResponse } from "@/types/attendance/types";
-import { ScheduleProp } from "@/types/schedule";
import { useQuery } from "@tanstack/react-query";
-export const useAttendanceListQuery = ({
- clubId,
-}: Omit) => {
+export const useAttendanceListQuery = (clubId: number) => {
return useQuery>({
- queryKey: [`attendanceList`, { clubId }],
+ queryKey: [`attendanceList`, clubId],
queryFn: () =>
http.get>(
- `/${clubId}/attendance-list`,
- {
- headers: { accept: "*/*" },
- }
+ `/clubs/${clubId}/schedules/attendance-ongoing`
),
});
};
diff --git a/src/hook/clubJoin/useJoinCancelMutation.ts b/src/hook/clubJoin/useJoinCancelMutation.ts
index 29d78ab..297aaae 100644
--- a/src/hook/clubJoin/useJoinCancelMutation.ts
+++ b/src/hook/clubJoin/useJoinCancelMutation.ts
@@ -1,12 +1,16 @@
import { http } from "@/apis/http";
-import { useMutation } from "@tanstack/react-query";
+import { useMutation, useQueryClient } from "@tanstack/react-query";
export const useJoinCancelMutation = (joinRequestId: number) => {
+ const queryClient = useQueryClient();
return useMutation({
- mutationFn: () => http.post(`/join/requests/${joinRequestId}/cancel`,``),
+ mutationFn: () => http.post(`/clubs/join/${joinRequestId}/cancel`),
onSuccess: (res) => {
- alert("삭제 성공");
+ alert("취소 성공");
console.log(res);
+ queryClient.invalidateQueries({
+ queryKey: ["JoinRequest"], //신청 목록 재확인
+ });
},
onError: (err) => {
console.log(err);
diff --git a/src/hook/clubJoin/useJoinClubQuery.ts b/src/hook/clubJoin/useJoinClubQuery.ts
new file mode 100644
index 0000000..176cc32
--- /dev/null
+++ b/src/hook/clubJoin/useJoinClubQuery.ts
@@ -0,0 +1,18 @@
+import { http } from "@/apis/http";
+import { CommonNoPageRes } from "@/types";
+import { JoinClub } from "@/types/clubjoin";
+import { useQuery } from "@tanstack/react-query";
+
+export const useJoinClubQuery = (privateCode: string) => {
+ return useQuery>({
+ queryKey: ["JoinClub"],
+ queryFn: async () =>
+ await http.get>(`/clubs?privateCode=${privateCode}`),
+ });
+};
+
+export const fetchJoinClub = async (privateCode: string) => {
+ const response = await http.get>(`/clubs?privateCode=${privateCode}`);
+ console.log(response);
+ return response;
+};
\ No newline at end of file
diff --git a/src/hook/clubJoin/useJoinDeleteMutation.ts b/src/hook/clubJoin/useJoinDeleteMutation.ts
new file mode 100644
index 0000000..4440f54
--- /dev/null
+++ b/src/hook/clubJoin/useJoinDeleteMutation.ts
@@ -0,0 +1,20 @@
+import { http } from "@/apis/http";
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+
+// 모임가입 신청 삭제
+export const useJoinDeleteMutation = (joinRequestId: number) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: () => http.delete(`/clubs/join/${joinRequestId}`),
+ onSuccess: (res) => {
+ alert("삭제 성공");
+ console.log(res);
+ queryClient.invalidateQueries({
+ queryKey: ["JoinRequest"], //신청 목록 재확인
+ });
+ },
+ onError: (err) => {
+ console.log(err);
+ },
+ });
+};
diff --git a/src/hook/clubJoin/useJoinRejectedQuery.ts b/src/hook/clubJoin/useJoinRejectedQuery.ts
index 5b29f6a..23152ed 100644
--- a/src/hook/clubJoin/useJoinRejectedQuery.ts
+++ b/src/hook/clubJoin/useJoinRejectedQuery.ts
@@ -1,14 +1,19 @@
import { http } from "@/apis/http";
+import { CommonNoPageRes } from "@/types";
import { JoinRequest } from "@/types/clubjoin";
import { useQuery } from "@tanstack/react-query";
+// 모임가입 신청 거절 사유 조회
export const useJoinRejectedQuery = (joinRequestId: number, status: string) => {
- return useQuery({
+ return useQuery>({
queryKey: ["JoinRejected", joinRequestId],
enabled: status === "REJECTED",
queryFn: async () =>
- await http.get(`/join/requests/${joinRequestId}`, {
- headers: { accept: `*/*` },
- }),
+ await http.get>(
+ `/clubs/join/${joinRequestId}`,
+ {
+ headers: { accept: `*/*` },
+ }
+ ),
});
};
diff --git a/src/hook/clubJoin/useJoinRequestsQuery.ts b/src/hook/clubJoin/useJoinRequestsQuery.ts
index 9a3f30e..9253626 100644
--- a/src/hook/clubJoin/useJoinRequestsQuery.ts
+++ b/src/hook/clubJoin/useJoinRequestsQuery.ts
@@ -3,11 +3,12 @@ import { CommonRes } from "@/types";
import { PageProps } from "@/types/pages";
import { useQuery } from "@tanstack/react-query";
+// 모임가입 신청내역 조회
export const useJoinRequestsQuery = ({ page, size }: PageProps) => {
return useQuery>({
queryKey: ["JoinRequest", { page, size }],
queryFn: () =>
- http.get>(`/join/requests?page=${page}&size=${size}`, {
+ http.get>(`/clubs/join?page=${page}&size=${size}`, {
headers: { accept: `*/*` },
}),
});
diff --git a/src/hook/comment/useCommentChangeMutation.ts b/src/hook/comment/useCommentChangeMutation.ts
new file mode 100644
index 0000000..766af1b
--- /dev/null
+++ b/src/hook/comment/useCommentChangeMutation.ts
@@ -0,0 +1,22 @@
+import { http } from "@/apis/http";
+import { postKeys } from "@/constants/keys/postKey";
+import { CommentData } from "@/types/comment";
+import { PostDetailProps } from "@/types/post";
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+
+export const useCommentChangeMutation = ({
+ clubId,
+ postId,
+}: PostDetailProps) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: (data: CommentData) =>
+ http.post(`/clubs/${clubId}/comment/updata`, data),
+ onSuccess: (data) => {
+ queryClient.invalidateQueries({
+ queryKey: [postKeys.comment({ clubId, postId })],
+ });
+ console.log(data);
+ },
+ });
+};
diff --git a/src/hook/comment/useCommentChildMutation.ts b/src/hook/comment/useCommentChildMutation.ts
new file mode 100644
index 0000000..6699aeb
--- /dev/null
+++ b/src/hook/comment/useCommentChildMutation.ts
@@ -0,0 +1,22 @@
+import { http } from "@/apis/http";
+import { postKeys } from "@/constants/keys/postKey";
+import { CommentData } from "@/types/comment";
+import { PostDetailProps } from "@/types/post";
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+
+export const useCommentChildMutation = ({
+ clubId,
+ postId,
+}: PostDetailProps) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: (data: CommentData) =>
+ http.post(`/clubs/${clubId}/comment/child`, data),
+ onSuccess: (data) => {
+ queryClient.invalidateQueries({
+ queryKey: [postKeys.comment({ clubId, postId })],
+ });
+ console.log(data);
+ },
+ });
+};
diff --git a/src/hook/comment/useCommentDeleteMutation.ts b/src/hook/comment/useCommentDeleteMutation.ts
new file mode 100644
index 0000000..3f3f55f
--- /dev/null
+++ b/src/hook/comment/useCommentDeleteMutation.ts
@@ -0,0 +1,22 @@
+import { http } from "@/apis/http";
+import { postKeys } from "@/constants/keys/postKey";
+import { CommantDeleteProps } from "@/types/comment";
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+
+export const useCommentDeleteMutation = ({
+ clubId,
+ postId,
+ commentId,
+}: CommantDeleteProps) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: () =>
+ http.post(`/clubs/${clubId}/comment/${commentId}/delete`),
+ onSuccess: (data) => {
+ queryClient.invalidateQueries({
+ queryKey: [postKeys.comment({ clubId, postId })],
+ });
+ console.log(data);
+ },
+ });
+};
diff --git a/src/hook/comment/useCommentMutation.ts b/src/hook/comment/useCommentMutation.ts
new file mode 100644
index 0000000..69570a7
--- /dev/null
+++ b/src/hook/comment/useCommentMutation.ts
@@ -0,0 +1,19 @@
+import { http } from "@/apis/http";
+import { postKeys } from "@/constants/keys/postKey";
+import { CommentData } from "@/types/comment";
+import { PostDetailProps } from "@/types/post";
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+
+export const useCommentMutation = ({ clubId, postId }: PostDetailProps) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: (data: CommentData) =>
+ http.post(`/clubs/${clubId}/comment`, data),
+ onSuccess: (data) => {
+ queryClient.invalidateQueries({
+ queryKey: [postKeys.comment({ clubId, postId })],
+ });
+ console.log(data);
+ },
+ });
+};
diff --git a/src/hook/comment/useCommentSort.ts b/src/hook/comment/useCommentSort.ts
new file mode 100644
index 0000000..fc3c958
--- /dev/null
+++ b/src/hook/comment/useCommentSort.ts
@@ -0,0 +1,34 @@
+import { Comment as CommentProps } from "@/types/comment";
+
+interface CommentSortInterface extends CommentProps {
+ replies: CommentProps[];
+}
+export const useCommentSort = (comentArr: CommentProps[] | undefined) => {
+ if (comentArr == undefined) {
+ return;
+ }
+ const structuredComments: CommentSortInterface[] = [];
+ const sortedComments = comentArr.sort((a, b) => {
+ if (a.parentId === null && b.parentId !== null) return -1;
+ if (a.parentId !== null && b.parentId === null) return 1;
+ return 0;
+ });
+
+ sortedComments.forEach((comment) => {
+ if (comment.parentId === null) {
+ structuredComments.push({
+ ...comment,
+ replies: [],
+ });
+ } else {
+ const parentIndex = structuredComments.findIndex(
+ (c) => c.commentId === comment.parentId
+ );
+ if (parentIndex !== -1) {
+ structuredComments[parentIndex].replies.push(comment);
+ }
+ }
+ });
+ console.log(structuredComments);
+ return structuredComments;
+};
diff --git a/src/hook/comment/useCommentsQuery.ts b/src/hook/comment/useCommentsQuery.ts
new file mode 100644
index 0000000..7551642
--- /dev/null
+++ b/src/hook/comment/useCommentsQuery.ts
@@ -0,0 +1,28 @@
+import { http } from "@/apis/http";
+import { postKeys } from "@/constants/keys/postKey";
+import { CommonRes } from "@/types";
+import { Comment } from "@/types/comment";
+import { PostDetailProps } from "@/types/post";
+import { useQuery } from "@tanstack/react-query";
+
+interface commentListProps extends PostDetailProps {
+ size: number;
+ page: number;
+}
+
+export const useCommentsQuery = ({
+ clubId,
+ postId,
+ size,
+ page,
+}: commentListProps) => {
+ return useQuery>({
+ queryKey: [postKeys.comment({ clubId, postId })],
+ queryFn: async () =>
+ await http.get>(
+ `/clubs/${clubId}/comment/${postId}?size=${size}&page=${page}`
+ ),
+ });
+};
+
+export default useCommentsQuery;
diff --git a/src/hook/info/useMyPostLikeQuery.ts b/src/hook/info/useMyPostLikeQuery.ts
new file mode 100644
index 0000000..d30a7c8
--- /dev/null
+++ b/src/hook/info/useMyPostLikeQuery.ts
@@ -0,0 +1,23 @@
+import { http } from "@/apis/http";
+import { CommonRes } from "@/types";
+import { MyPostProps } from "@/types/info";
+import { PostList } from "@/types/post";
+import { useQuery } from "@tanstack/react-query";
+
+export const useMyPostLikeQuery = ({
+ clubId,
+ userId,
+ category,
+ page,
+ size,
+ sort="",
+}: MyPostProps) => {
+ const myPostUrl = `/clubs/${clubId}/posts/my_like_posts?userId=${userId}&postCategory=${category}&page=${page}&size=${size}&sort=${sort}`;
+ return useQuery>({
+ queryKey: ["postMyLikePost", { clubId, category, size, page, sort }],
+ queryFn: async () =>
+ await http.get>(myPostUrl)
+ });
+};
+
+export default useMyPostLikeQuery;
\ No newline at end of file
diff --git a/src/hook/info/useMyPostQuery.ts b/src/hook/info/useMyPostQuery.ts
new file mode 100644
index 0000000..4395c23
--- /dev/null
+++ b/src/hook/info/useMyPostQuery.ts
@@ -0,0 +1,22 @@
+import { http } from "@/apis/http";
+import { CommonRes } from "@/types";
+import { MyPostProps } from "@/types/info";
+import { PostList } from "@/types/post";
+import { useQuery } from "@tanstack/react-query";
+
+export const useMyPostQuery = ({
+ clubId,
+ category,
+ page,
+ size,
+ sort="",
+}: MyPostProps) => {
+ const myPostUrl = `/clubs/${clubId}/posts/my_posts?postCategory=${category}&page=${page}&size=${size}&sort=${sort}`;
+ return useQuery>({
+ queryKey: ["postMyPost", { clubId, category, size, page, sort }],
+ queryFn: async () =>
+ await http.get>(myPostUrl)
+ });
+};
+
+export default useMyPostQuery;
\ No newline at end of file
diff --git a/src/hook/post/usePostDeleteMutation.ts b/src/hook/post/usePostDeleteMutation.ts
new file mode 100644
index 0000000..e94aee7
--- /dev/null
+++ b/src/hook/post/usePostDeleteMutation.ts
@@ -0,0 +1,18 @@
+import { http } from "@/apis/http";
+import { PostDetailProps } from "@/types/post";
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+import { useRouter } from "next/navigation";
+
+export const usePostDeleteMutation = ({ clubId, postId }: PostDetailProps) => {
+ const queryClient = useQueryClient();
+ const router = useRouter();
+ return useMutation({
+ mutationFn: () => http.delete(`/clubs/${clubId}/posts/${postId}/delete`),
+ onSuccess: () => {
+ router.back();
+ queryClient.invalidateQueries({
+ queryKey: ["postList"],
+ });
+ },
+ });
+};
diff --git a/src/hook/post/usePostDetailQuery.ts b/src/hook/post/usePostDetailQuery.ts
index be2d27e..14f68f4 100644
--- a/src/hook/post/usePostDetailQuery.ts
+++ b/src/hook/post/usePostDetailQuery.ts
@@ -1,18 +1,14 @@
import { http } from "@/apis/http";
-import { CommonRes } from "@/types";
-import { PostDetailProps } from "@/types/post";
+import { postKeys } from "@/constants/keys/postKey";
+import { CommonNoPageRes } from "@/types";
+import { PostDetailProps, PostList } from "@/types/post";
import { useQuery } from "@tanstack/react-query";
export const usePostDetailQuery = ({ clubId, postId }: PostDetailProps) => {
- return useQuery>({
- queryKey: ["postDetail", clubId, postId],
- queryFn: async () => {
- const response = await http.get>(
- `clubs/4/posts/9`
- );
- return response;
- },
- staleTime: 1000,
+ return useQuery>({
+ queryKey: [postKeys.detail({ clubId, postId })],
+ queryFn: async () =>
+ await http.get>(`/clubs/${clubId}/posts/${postId}`),
});
};
diff --git a/src/hook/post/usePostListQuery.ts b/src/hook/post/usePostListQuery.ts
new file mode 100644
index 0000000..aa92435
--- /dev/null
+++ b/src/hook/post/usePostListQuery.ts
@@ -0,0 +1,37 @@
+import { http } from "@/apis/http";
+import { CommonRes } from "@/types";
+import { PostList } from "@/types/post";
+import { useQuery } from "@tanstack/react-query";
+
+interface props {
+ clubId: number;
+ keyword?: string;
+ category: "NOTICE" | "FREE";
+ startData?: string;
+ endData?: string;
+ page: number;
+ size: number;
+ sort?: string;
+}
+export const usePostListQuery = ({
+ clubId,
+ keyword = "",
+ category,
+ startData,
+ endData,
+ page,
+ size,
+ sort = "string",
+}: props) => {
+ const keywordUrl = `/clubs/${clubId}/posts?keyword=${keyword}&sortBy=createAt&category=${category}&page=${page}&size=${size}`;
+ const datePullUrl = `/clubs/${clubId}/posts?keyword=${keyword}&startDate=${startData}&endData=${endData}&sortBy=createAt&page=${page}&size=${size}`;
+ return useQuery>({
+ queryKey: ["postList", { clubId, category, size, page, sort }],
+ queryFn: async () =>
+ await http.get>(keywordUrl, {
+ headers: { accept: "*/*" },
+ }),
+ });
+};
+
+export default usePostListQuery;
diff --git a/src/hook/post/usePostMutation.ts b/src/hook/post/usePostMutation.ts
index a8e9954..4fd8943 100644
--- a/src/hook/post/usePostMutation.ts
+++ b/src/hook/post/usePostMutation.ts
@@ -1,6 +1,6 @@
import { http } from "@/apis/http";
import { PostFormProps } from "@/types/post";
-import { useMutation } from "@tanstack/react-query";
+import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useRouter } from "next/navigation";
async function registePost(postData: PostFormProps) {
@@ -47,9 +47,13 @@ interface UseRegistePost {
}
export function usePostMutation(): UseRegistePost {
const router = useRouter();
+ const queryClient = useQueryClient();
const { mutate } = useMutation({
mutationFn: registePost,
onSuccess: () => {
+ queryClient.invalidateQueries({
+ queryKey: ["postList"],
+ });
console.log("게시글 등록 성공");
router.back();
},
diff --git a/src/hook/post/useheartMutation.ts b/src/hook/post/useheartMutation.ts
new file mode 100644
index 0000000..848a9c0
--- /dev/null
+++ b/src/hook/post/useheartMutation.ts
@@ -0,0 +1,27 @@
+import { http } from "@/apis/http";
+import { postKeys } from "@/constants/keys/postKey";
+import { PostDetailProps } from "@/types/post";
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+
+export const useHeartMutation = ({ clubId, postId }: PostDetailProps) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: () => http.post(`/clubs/${clubId}/posts/${postId}/like`),
+ onSuccess: () => {
+ queryClient.invalidateQueries({
+ queryKey: [postKeys.detail({ postId, clubId })],
+ });
+ },
+ });
+};
+export const useHeartCancleMutation = ({ clubId, postId }: PostDetailProps) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: () => http.delete(`/clubs/${clubId}/posts/${postId}/like`),
+ onSuccess: () => {
+ queryClient.invalidateQueries({
+ queryKey: [postKeys.detail({ postId, clubId })],
+ });
+ },
+ });
+};
diff --git a/src/hook/schedule/useDebounce.ts b/src/hook/schedule/useDebounce.ts
new file mode 100644
index 0000000..f673a39
--- /dev/null
+++ b/src/hook/schedule/useDebounce.ts
@@ -0,0 +1,18 @@
+import { useEffect, useState } from "react";
+
+export const useDebounce = ({keyword, delay = 500}: {
+ keyword: string;
+ delay?: number;
+}) => {
+ const [debouncedValue, setDebouncedValue] = useState(keyword);
+
+ useEffect(() => {
+ const handler = setTimeout(() => {
+ setDebouncedValue(keyword);
+ }, delay);
+
+ return () => clearTimeout(handler);
+ }, [keyword]);
+
+ return debouncedValue;
+}
\ No newline at end of file
diff --git a/src/hook/schedule/useSchedule.ts b/src/hook/schedule/useSchedule.ts
index bbe9eeb..2ac60fe 100644
--- a/src/hook/schedule/useSchedule.ts
+++ b/src/hook/schedule/useSchedule.ts
@@ -1,38 +1,44 @@
import { changeMonth, filterDate } from "@/features/home/utils";
import { getScheduleExist } from "@/features/home/utils/util";
-import { FetchScheduleParams } from "@/types/schedule";
+import { FetchScheduleParams, ScheduleDate, ScheduleKeyword } from "@/types/schedule";
import moment from "moment";
import { useState } from "react";
import { useScheduleQuery } from "./useScheduleQuery";
const useSchedule = (
{
- clubId, q, sDate, eDate
+ clubId, keyword, startDate, endDate, page, size
}: FetchScheduleParams
) => {
const [value, setValue] = useState(new Date());
const [params, setParams] = useState({
clubId: clubId,
- q: q,
- sDate: sDate,
- eDate: eDate
+ keyword: keyword,
+ startDate: startDate,
+ endDate: endDate,
+ page: page,
+ size: size
})
// params에 맞는 일정 fetch
const { data, isLoading } = useScheduleQuery(params);
// params 변경
- const refetchSchedule = ({
- clubId,
- q,
- sDate,
- eDate
- }: FetchScheduleParams) => setParams({
- clubId: clubId,
- q: q,
- sDate: sDate,
- eDate: eDate
- })
+ const refetchPeriodSchedule = ({
+ startDate,
+ endDate
+ }: ScheduleDate) => setParams((prev) => ({
+ ...prev,
+ startDate: startDate,
+ endDate: endDate
+ }))
+
+ const refetchKeywordSchedule = ({
+ keyword
+ }: ScheduleKeyword) => setParams((prev) => ({
+ ...prev,
+ keyword: keyword
+ }))
// 일정 변경 시 실행 function
const handleChange = (newValue: Date) => {
@@ -46,8 +52,8 @@ const useSchedule = (
// 달 변경 시 해당 달 일정 새로 fetch
isChn && setParams({
...params,
- sDate: moment(newValue).startOf('month').format("YYYY-MM-DD"),
- eDate: moment(newValue).endOf('month').format("YYYY-MM-DD")
+ startDate: moment(newValue).startOf('month').format("YYYY-MM-DD"),
+ endDate: moment(newValue).endOf('month').format("YYYY-MM-DD")
})
};
@@ -65,7 +71,8 @@ const useSchedule = (
return {
value,
setValue: handleChange,
- refetchSchedule,
+ refetchPeriodSchedule,
+ refetchKeywordSchedule,
filteredData,
data,
isLoading,
diff --git a/src/hook/schedule/useScheduleQuery.ts b/src/hook/schedule/useScheduleQuery.ts
index b4258c1..e2d4f74 100644
--- a/src/hook/schedule/useScheduleQuery.ts
+++ b/src/hook/schedule/useScheduleQuery.ts
@@ -4,12 +4,20 @@ import { FetchScheduleParams, ScheduleContent } from "@/types/schedule";
import { useQuery } from "@tanstack/react-query";
// 일정 조회 (/clubs/{clubs}/schedules)
-export const useScheduleQuery = ({ clubId, q, sDate, eDate }: FetchScheduleParams) => {
+export const useScheduleQuery = ({
+ clubId,
+ keyword,
+ startDate,
+ endDate,
+ page,
+ size,
+ sort = "string",
+}: FetchScheduleParams) => {
return useQuery>({
- queryKey: ['schedule', clubId, q, sDate, eDate],
+ queryKey: ['schedule', {clubId, keyword, startDate, endDate, page, size, sort}],
queryFn: async () => {
const response = await http.get>(
- `/clubs/${clubId}/schedules?q=${q}&sDate=${sDate}&eDate=${eDate}`
+ `/clubs/${clubId}/schedules?keyword=${keyword}&startDate=${startDate}&endDate=${endDate}&page=${page}&size=${size}`
);
return response;
},
diff --git a/src/hook/user/useClubListQuery.ts b/src/hook/user/useClubListQuery.ts
index 75ffc8b..915fb5e 100644
--- a/src/hook/user/useClubListQuery.ts
+++ b/src/hook/user/useClubListQuery.ts
@@ -4,12 +4,13 @@ import { Club } from "@/types/club";
import { PageProps } from "@/types/pages";
import { useQuery } from "@tanstack/react-query";
+// 가입한 모임 조회
export const useClubListQuery = ({ page, size }: PageProps) => {
return useQuery>({
queryKey: [`clubList`, { page, size }],
queryFn: () =>
http.get>(
- `/clubs?page=${page}&size=${size}`,
+ `/clubs/my?page=${page}&size=${size}`,
{ headers: { accept: "*/*" } }
),
});
diff --git a/src/hook/user/useGetUserInfoQuery.ts b/src/hook/user/useGetUserInfoQuery.ts
new file mode 100644
index 0000000..7b74a7f
--- /dev/null
+++ b/src/hook/user/useGetUserInfoQuery.ts
@@ -0,0 +1,16 @@
+import { http } from "@/apis/http";
+import { CommonNoPageRes } from "@/types";
+import { signUpInfo, userInfo } from "@/types/user/types";
+import { useQuery } from "@tanstack/react-query";
+
+export const useGetUserInfoQuery = () => {
+ return useQuery>({
+ queryKey: ["userInfo"],
+ queryFn: async () => {
+ const response =
+ await http.get>(`/user/getInfo`);
+ return response;
+ },
+ staleTime: 1000,
+ });
+};
diff --git a/src/hook/user/useModificationUserInfoMutation.ts b/src/hook/user/useModificationUserInfoMutation.ts
new file mode 100644
index 0000000..f8ba8e5
--- /dev/null
+++ b/src/hook/user/useModificationUserInfoMutation.ts
@@ -0,0 +1,12 @@
+import { http } from "@/apis/http";
+import { signUpInfo } from "@/types/user/types";
+import { useMutation } from "@tanstack/react-query";
+
+export const useModificationUserInfoMutation = () => {
+ return useMutation({
+ mutationFn: (data: signUpInfo) => http.post(`/user/modification`, data),
+ onSuccess: (data) => {
+ console.log(data);
+ },
+ });
+};
diff --git a/src/hook/user/useUserMutation.ts b/src/hook/user/useUserMutation.ts
index 6491c6b..7663483 100644
--- a/src/hook/user/useUserMutation.ts
+++ b/src/hook/user/useUserMutation.ts
@@ -1,25 +1,20 @@
import { http } from "@/apis/http";
+import { signUpInfo } from "@/types/user/types";
import { useMutation } from "@tanstack/react-query";
import { useRouter } from "next/navigation";
-export interface CreateUserProps {
- userName: string;
- userPhone: string;
- userEmail: string;
-}
-
// 추가 회원가입 (/user/signUp)
export const useUserMutation = () => {
const router = useRouter();
return useMutation({
- mutationFn: (data: CreateUserProps) => http.post('/user/signUp', data),
+ mutationFn: (data: signUpInfo) => http.post("/user/signUp", data),
onSuccess: (res) => {
- alert('회원가입 성공!');
+ alert("회원가입 성공!");
console.log(res);
router.push("/user/signup/complete");
},
onError: (err) => {
console.log(err);
- }
- })
-}
\ No newline at end of file
+ },
+ });
+};
diff --git a/src/types/attendance/types.ts b/src/types/attendance/types.ts
index 6e1efec..a24534b 100644
--- a/src/types/attendance/types.ts
+++ b/src/types/attendance/types.ts
@@ -20,13 +20,20 @@ export type GetAttendanceListResponse = AttendanceListItem[];
// 오늘의 일정
export interface TodayScheduleItem
- extends Omit {
- sDate: string;
- eDate: string;
+ extends Omit {
+ clubId: number;
+ startDate: string;
+ endDate: string;
}
// 출석 아이템
export interface AttendanceSchedule extends ScheduleContent {
+ isSuccess?: boolean;
attendanceAddress: string;
onClick: () => void;
}
+
+// 출석하기
+export interface AttendanceReqData {
+ attendanceNum: number;
+}
diff --git a/src/types/club/types.ts b/src/types/club/types.ts
index c1bfb7c..eac91f0 100644
--- a/src/types/club/types.ts
+++ b/src/types/club/types.ts
@@ -1,4 +1,3 @@
-
// 클럽 기본 구조
export interface Club {
clubId: number;
@@ -20,6 +19,7 @@ export enum ApprovalStatus {
Approved = "ACCEPTED",
Waiting = "WAITING",
Rejected = "REJECTED",
+ Cancel = "CANCELED",
}
// 클럽 생성 폼
@@ -61,9 +61,9 @@ export interface ClubProfiles {
}
export interface ClubInfos {
- clubIntro?: string
+ clubIntro?: string;
isPrivate?: boolean;
contactMeans?: string | string[];
namePolicy?: "NICK_NAME" | "REAL_NAME";
memberCount?: number;
-}
\ No newline at end of file
+}
diff --git a/src/types/comment/index.ts b/src/types/comment/index.ts
new file mode 100644
index 0000000..516c191
--- /dev/null
+++ b/src/types/comment/index.ts
@@ -0,0 +1,2 @@
+export * from "./types";
+
diff --git a/src/types/comment/types.ts b/src/types/comment/types.ts
new file mode 100644
index 0000000..ea84526
--- /dev/null
+++ b/src/types/comment/types.ts
@@ -0,0 +1,31 @@
+import { PostDetailProps } from "../post";
+
+// 클럽 조회 페이지
+export interface Comment {
+ commentId: number;
+ memberId: number;
+ postId: number;
+ parentId: null | number;
+ content: string;
+ createdAt: string;
+ updateAt: string;
+}
+
+export interface CommentData {
+ postId: number;
+ content: string;
+ parentId?: number;
+}
+export interface CommantDeleteProps extends PostDetailProps{
+ commentId: number;
+}
+export interface CommentsProps {
+ item: Comment;
+ onClick: (commentId: number) => void;
+}
+export interface CommentsListProps {
+ item: Comment;
+ replies?: Comment[];
+ onClick: (commentId: number) => void;
+}
+
diff --git a/src/types/info/index.ts b/src/types/info/index.ts
new file mode 100644
index 0000000..eea524d
--- /dev/null
+++ b/src/types/info/index.ts
@@ -0,0 +1 @@
+export * from "./types";
diff --git a/src/types/info/types.ts b/src/types/info/types.ts
new file mode 100644
index 0000000..c5801b1
--- /dev/null
+++ b/src/types/info/types.ts
@@ -0,0 +1,22 @@
+export interface MyPostProps {
+ clubId: number;
+ userId?: number;
+ category?: "NOTICE" | "FREE";
+ page: number;
+ size: number;
+ sort?: string;
+}
+
+export interface MyPostContent {
+ postId: number;
+ writerProfileImage: string;
+ writerName: string;
+ postTitle: string;
+ postContent: string;
+ uploadImage: string[] | null;
+ postCategory: "NOTICE" | "FREE";
+ postLikeCount: number;
+ commentCount: number;
+ isLiked: boolean;
+ createdAt: string;
+}
\ No newline at end of file
diff --git a/src/types/post/types.ts b/src/types/post/types.ts
index 948add0..326ebe2 100644
--- a/src/types/post/types.ts
+++ b/src/types/post/types.ts
@@ -12,3 +12,17 @@ export interface PostDetailProps {
clubId: number;
postId: number;
}
+
+export interface PostList {
+ postId: number;
+ writerProfileImage: string;
+ writerName: string;
+ postTitle: string;
+ postContent: string;
+ uploadImage: [string];
+ postCategory: "NOTICE" | "FREE";
+ postLikeCount: number;
+ isLiked: boolean;
+ commentCount: number;
+ createdAt: string;
+}
diff --git a/src/types/schedule/types.ts b/src/types/schedule/types.ts
index c288ccb..733a4cb 100644
--- a/src/types/schedule/types.ts
+++ b/src/types/schedule/types.ts
@@ -1,8 +1,8 @@
export enum Attendance {
- BEFORE = "BEFORE",
+ BEFORE = "BEFORE",
ONGOING = "ONGOING",
- COMPLETE = "COMPLETE"
-};
+ COMPLETE = "COMPLETE",
+}
// 일정 목록 data
export interface ScheduleContent {
@@ -13,11 +13,23 @@ export interface ScheduleContent {
attendanceStatus: Attendance;
}
+export interface ScheduleDate {
+ startDate?: string;
+ endDate?: string;
+}
+
+export interface ScheduleKeyword {
+ keyword?: string;
+}
+
export interface FetchScheduleParams {
clubId: number;
- q?: string;
- sDate?: string;
- eDate?: string;
+ keyword?: string;
+ startDate?: string;
+ endDate?: string;
+ page: number;
+ size: number;
+ sort?: string;
}
// 일정 박스
@@ -44,10 +56,9 @@ export interface ScheduleData {
}
// 일정 상세 data
-
export interface ScheduleDetailProp {
clubId: number;
- scheduleId: number
+ scheduleId: number;
}
export interface ScheduleDetailContent {
@@ -61,4 +72,4 @@ export interface ScheduleDetailContent {
registerProfileImage: string;
registrationDate: string;
attendanceStatus: Attendance;
-}
\ No newline at end of file
+}
diff --git a/src/types/user/types.ts b/src/types/user/types.ts
new file mode 100644
index 0000000..ad93209
--- /dev/null
+++ b/src/types/user/types.ts
@@ -0,0 +1,10 @@
+export interface signUpInfo {
+ userName: string;
+ userPhone: string;
+ userEmail: string;
+}
+
+export interface userInfo extends signUpInfo {
+ userId: number;
+ oauth2Id: string;
+}