|
1 |
| -import { useState } from "react"; |
| 1 | +import axios from "axios"; |
| 2 | +import { useNavigate } from "react-router-dom"; |
| 3 | +import { useState, useEffect } from "react"; |
| 4 | + |
| 5 | +import useAuth from "@/hooks/useAuth"; |
2 | 6 | import Button from "@/components/Button/Button";
|
3 |
| -import ProfileBig from "@/assets/imgs/profileBig.png"; |
4 |
| -import EnterIcon from "@/assets/svgs/enter.svg?react"; |
5 |
| -import { useToast } from "@/components/Toast/useToast"; |
6 | 7 | import ReplayLectureCard from "./ReplayLectureCard";
|
| 8 | +import { useToast } from "@/components/Toast/useToast"; |
7 | 9 |
|
8 |
| -interface MyPageSectionProps { |
9 |
| - profileImage: string; |
10 |
| -} |
| 10 | +import EnterIcon from "@/assets/svgs/enter.svg?react"; |
| 11 | +import ProfileBig from "@/assets/imgs/profileBig.png"; |
| 12 | +import SubLogoOriginal from "@/assets/imgs/subLogoOriginal.png"; |
11 | 13 |
|
12 |
| -const NICKNAME_REGEXP = /^(?![0-9-_.]+$)[๊ฐ-ํฃA-Za-z0-9-_.]{1,10}$/; |
| 14 | +const NICKNAME_REGEXP = /^[a-zA-Z0-9๊ฐ-ํฃ]{3,15}$/; |
13 | 15 |
|
14 |
| -const DUMMY_DATA = [ |
15 |
| - { |
16 |
| - profileImage: "", |
17 |
| - duration: "12:34", |
18 |
| - user: "๋ณผ๋ก์ด", |
19 |
| - date: "2023.11.11", |
20 |
| - title: "ํ๋ก๊ทธ๋๋ฐ ๊ธฐ์ด", |
21 |
| - description: "์ปดํจํฐ ํ๋ก๊ทธ๋๋ฐ์ ๊ธฐ๋ณธ ์๋ฆฌ๋ฅผ ๋ฐฐ์ฐ๋ ์
๋ฌธ ๊ฐ์ข. ์ธ์ด ์ ํ๋ถํฐ ๊ธฐ๋ณธ ๊ตฌ๋ฌธ๊น์ง." |
22 |
| - }, |
23 |
| - { |
24 |
| - profileImage: "", |
25 |
| - duration: "12:34", |
26 |
| - user: "๋ณผ๋ก์ด", |
27 |
| - date: "2023.11.12", |
28 |
| - title: "์๋ฆฌ์ ๊ธฐ์ด", |
29 |
| - description: "๊ธฐ๋ณธ์ ์ธ ์๋ฆฌ ๊ธฐ์ ๊ณผ ์๋ฆฌ๋ฒ์ ๋ฐฐ์ฐ๋ ๊ฐ์ข. ์ด๋ณด์๋ฅผ ์ํ ์ฌ์ด ๋ ์ํผ์ ์๋ฆฌ ํ ์ ๊ณต." |
30 |
| - }, |
31 |
| - { |
32 |
| - profileImage: "", |
33 |
| - duration: "12:34", |
34 |
| - user: "๋ณผ๋ก์ด", |
35 |
| - date: "2023.11.13", |
36 |
| - title: "๋์งํธ ๋ง์ผํ
", |
37 |
| - description: "๋์งํธ ๋ง์ผํ
์ ๋ต๊ณผ ์์
๋ฏธ๋์ด ํ์ฉ ๋ฐฉ๋ฒ์ ๋ฐฐ์ฐ๋ ์ค์ฉ์ ์ธ ๊ฐ์ข." |
38 |
| - }, |
39 |
| - { |
40 |
| - profileImage: "", |
41 |
| - duration: "12:34", |
42 |
| - user: "๋ณผ๋ก์ด", |
43 |
| - date: "2023.11.14", |
44 |
| - title: "์ํ์ ์ดํด", |
45 |
| - description: "๊ธฐ๋ณธ์ ์ธ ์ํ ๊ฐ๋
๊ณผ ๋ฌธ์ ํด๊ฒฐ ๊ธฐ์ ์ ๋ฐฐ์ฐ๋ ๊ฐ์ข. ์ํ์ ๋ํ ๋๋ ค์์ ๊ทน๋ณตํ ์ ์๋๋ก ๋์." |
46 |
| - }, |
47 |
| - { |
48 |
| - profileImage: "", |
49 |
| - duration: "12:34", |
50 |
| - user: "๋ณผ๋ก์ด", |
51 |
| - date: "2023.11.15", |
52 |
| - title: "์ญ์ฌ ํํ", |
53 |
| - description: "์ธ๊ณ ์ญ์ฌ์ ์ฃผ์ ์ฌ๊ฑด๊ณผ ์ธ๋ฌผ์ ํ๊ตฌํ๋ ๊ฐ์ข. ์ญ์ฌ๋ฅผ ํตํด ํ์ฌ๋ฅผ ์ดํดํ๋ ๋ฐ ๋์." |
54 |
| - }, |
55 |
| - { |
56 |
| - profileImage: "", |
57 |
| - duration: "12:34", |
58 |
| - user: "๋ณผ๋ก์ด", |
59 |
| - date: "2023.11.16", |
60 |
| - title: "์ฐฝ์์ ๊ธ์ฐ๊ธฐ", |
61 |
| - description: "์ฐฝ์์ ์ธ ๊ธ์ฐ๊ธฐ ๊ธฐ์ ๊ณผ ์์ด๋์ด ๋ฐ์๋ฒ์ ๋ฐฐ์ฐ๋ ๊ฐ์ข. ๊ธ์ฐ๊ธฐ๋ฅผ ํตํ ์๊ธฐ ํํ ๋ฐฉ๋ฒ ํ๊ตฌ." |
62 |
| - }, |
63 |
| - { |
64 |
| - profileImage: "", |
65 |
| - duration: "12:34", |
66 |
| - user: "๋ณผ๋ก์ด", |
67 |
| - date: "2023.11.17", |
68 |
| - title: "์ํ ๋ถ์", |
69 |
| - description: "์ํ์ ๊ธฐ์ ์ ์์์ ์์ ์ ๊ฐ์น๋ฅผ ๋ถ์ํ๋ ๊ฐ์ข. ์ํ๋ฅผ ๊น์ด ์๊ฒ ์ดํดํ๋ ๋ฐฉ๋ฒ ์ ๊ณต." |
70 |
| - }, |
71 |
| - { |
72 |
| - profileImage: "", |
73 |
| - duration: "12:34", |
74 |
| - user: "๋ณผ๋ก์ด", |
75 |
| - date: "2023.11.18", |
76 |
| - title: "ํผํธ๋์ค ๊ฐ์ด๋", |
77 |
| - description: "๊ฑด๊ฐํ๊ณ ํจ์จ์ ์ธ ์ด๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ฐ๋ ๊ฐ์ข. ๊ฐ์ธ๋ณ ๋ง์ถค ์ด๋ ๊ณํ ์ค์ ๋ฐฉ๋ฒ ์ ๊ณต." |
78 |
| - }, |
79 |
| - { |
80 |
| - profileImage: "", |
81 |
| - duration: "12:34", |
82 |
| - user: "๋ณผ๋ก์ด", |
83 |
| - date: "2023.11.19", |
84 |
| - title: "์ฌ์ง์ ์
๋ฌธ", |
85 |
| - description: "๊ธฐ์ด ์ฌ์ง ๊ธฐ์ ๊ณผ ๊ตฌ๋, ์กฐ๋ช
ํ์ฉ๋ฒ์ ๋ฐฐ์ฐ๋ ๊ฐ์ข. ์ฌ์ง์ ํตํด ์์ ์ ๊ฐ๊ฐ ํฅ์." |
86 |
| - }, |
87 |
| - { |
88 |
| - profileImage: "", |
89 |
| - duration: "12:34", |
90 |
| - user: "๋ณผ๋ก์ด", |
91 |
| - date: "2023.11.20", |
92 |
| - title: "ํ๊ฒฝ ๋ณดํธ", |
93 |
| - description: "ํ๊ฒฝ ๋ณดํธ์ ์ง์ ๊ฐ๋ฅํ ์ํ ๋ฐฉ์์ ๋ํด ๋ฐฐ์ฐ๋ ๊ฐ์ข. ์ผ์์์ ์ค์ฒํ ์ ์๋ ํ๊ฒฝ ๋ณดํธ ํ๋ ์๊ฐ." |
94 |
| - } |
95 |
| -]; |
| 16 | +type Lecture = { |
| 17 | + date: string; |
| 18 | + duration: string; |
| 19 | + user: string; |
| 20 | + title: string; |
| 21 | + description: string; |
| 22 | +}; |
96 | 23 |
|
97 |
| -const MyPageSection = ({ profileImage }: MyPageSectionProps) => { |
| 24 | +const MyPageSection = () => { |
98 | 25 | const showToast = useToast();
|
99 |
| - const [nickname, setNickname] = useState("๋ณผ๋ก์ด"); |
100 |
| - const [isNicknameEdit, setIsNicknameEdit] = useState(false); |
| 26 | + const navigate = useNavigate(); |
| 27 | + const { checkAuth } = useAuth(); |
| 28 | + const [username, setUsername] = useState(localStorage.getItem("username") || ""); |
| 29 | + const [isUsernameEdit, setIsUsernameEdit] = useState(false); |
101 | 30 | const [isValid, setIsValid] = useState(true);
|
| 31 | + const [lectureList, setLectureList] = useState<Lecture[]>([]); |
| 32 | + |
| 33 | + useEffect(() => { |
| 34 | + checkAuth(); |
| 35 | + axios |
| 36 | + .get(`${import.meta.env.VITE_API_SERVER_URL}/lecture/list`, { |
| 37 | + headers: { Authorization: localStorage.getItem("token") } |
| 38 | + }) |
| 39 | + .then((result) => { |
| 40 | + setLectureList(result.data); |
| 41 | + }) |
| 42 | + .catch((error) => { |
| 43 | + if (error.response.status === 401) { |
| 44 | + showToast({ message: "๋ก๊ทธ์ธ์ด ๋ง๋ฃ๋์์ด์.", type: "alert" }); |
| 45 | + navigate("/userauth"); |
| 46 | + } else showToast({ message: "์ ๋ณด๋ฅผ ๋ถ๋ฌ์ค๋๋ฐ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ด์.", type: "alert" }); |
| 47 | + }); |
| 48 | + }, []); |
102 | 49 |
|
103 | 50 | const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
104 |
| - const newNickname = event.target.value; |
105 |
| - setNickname(newNickname); |
106 |
| - setIsValid(NICKNAME_REGEXP.test(newNickname)); |
| 51 | + const newUsername = event.target.value; |
| 52 | + setUsername(newUsername); |
| 53 | + setIsValid(NICKNAME_REGEXP.test(newUsername)); |
107 | 54 | };
|
108 | 55 |
|
109 | 56 | const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
110 | 57 | if (e.key === "Enter") handleEditButtonClicked();
|
111 | 58 | };
|
112 | 59 |
|
113 | 60 | const handleEditButtonClicked = () => {
|
114 |
| - if (isNicknameEdit) { |
| 61 | + if (isUsernameEdit) { |
115 | 62 | if (isValid) {
|
| 63 | + axios |
| 64 | + .post( |
| 65 | + `${import.meta.env.VITE_API_SERVER_URL}/profile`, |
| 66 | + { username }, |
| 67 | + { |
| 68 | + headers: { Authorization: localStorage.getItem("token") } |
| 69 | + } |
| 70 | + ) |
| 71 | + .then((response) => { |
| 72 | + const { username, email } = response.data; |
| 73 | + localStorage.setItem("username", username); |
| 74 | + localStorage.setItem("email", email); |
| 75 | + setUsername(username); |
| 76 | + }) |
| 77 | + .catch((error) => { |
| 78 | + if (error.response.status === 401) { |
| 79 | + showToast({ message: "๋ก๊ทธ์ธ์ด ๋ง๋ฃ๋์์ด์.", type: "alert" }); |
| 80 | + navigate("/userauth"); |
| 81 | + } else showToast({ message: "์ ๋ณด๋ฅผ ๋ถ๋ฌ์ค๋๋ฐ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ด์.", type: "alert" }); |
| 82 | + }); |
116 | 83 | showToast({ message: "๋๋ค์ ๋ณ๊ฒฝ์ ์๋ฃํ์ต๋๋ค.", type: "success" });
|
117 |
| - setIsNicknameEdit(false); |
| 84 | + setIsUsernameEdit(false); |
118 | 85 | } else {
|
119 | 86 | showToast({ message: "์ฌ๋ฐ๋ฅด์ง ์์ ๋๋ค์์
๋๋ค.", type: "alert" });
|
120 | 87 | }
|
121 | 88 | } else {
|
122 | 89 | showToast({ message: "๋๋ค์์ ๋ณ๊ฒฝํฉ๋๋ค.", type: "default" });
|
123 |
| - setIsNicknameEdit(true); |
| 90 | + setIsUsernameEdit(true); |
124 | 91 | }
|
125 | 92 | };
|
126 | 93 |
|
127 | 94 | return (
|
128 | 95 | <div className="flex flex-col items-center my-32 sm:mt-36">
|
129 | 96 | <section className="flex relative w-11/12 max-w-3xl p-6 flex-col items-center gap-6 rounded-2xl border-default shadow-xl">
|
130 |
| - <img |
131 |
| - src={profileImage ? profileImage : ProfileBig} |
132 |
| - alt="ํ๋กํ ์ด๋ฏธ์ง" |
133 |
| - className="absolute -top-20 w-40 h-40 sm:w-56 sm:h-56 sm:-top-28" |
134 |
| - /> |
| 97 | + <img src={ProfileBig} alt="ํ๋กํ ์ด๋ฏธ์ง" className="absolute -top-20 w-40 h-40 sm:w-56 sm:h-56 sm:-top-28" /> |
135 | 98 |
|
136 | 99 | <input
|
137 | 100 | type="text"
|
138 |
| - value={nickname} |
| 101 | + value={username} |
139 | 102 | onChange={handleChange}
|
140 | 103 | onKeyDown={handleKeyDown}
|
141 |
| - size={nickname.length + 1 || 3} |
| 104 | + size={username.length + 1 || 3} |
142 | 105 | placeholder="๋๋ค์"
|
143 | 106 | maxLength={10}
|
144 |
| - disabled={!isNicknameEdit} |
| 107 | + disabled={!isUsernameEdit} |
145 | 108 | className="mt-20 sm:mt-28 semibold-32 text-center border-b-2 border-grayscale-gray focus:border-grayscale-black outline-none transition duration-200 rounded-none disabled:border-none disabled:text-grayscale-black disabled:bg-grayscale-white"
|
146 | 109 | />
|
147 | 110 |
|
148 | 111 | <div className="flex flex-col gap-1 justify-center items-center">
|
149 |
| - {isNicknameEdit ? ( |
| 112 | + {isUsernameEdit ? ( |
150 | 113 | <>
|
151 | 114 | {" "}
|
152 | 115 | <p className="semibold-18 text-grayscale-darkgray">์ฌ์ฉํ ๋๋ค์์ ์
๋ ฅํด ์ฃผ์ธ์.</p>
|
153 | 116 | <p className={`medium-12 ${isValid ? "text-boarlog-100" : "text-alert-100"}`}>
|
154 |
| - ํ๊ธ, ์๋ฌธ, ์ซ์, -, _, ., ์ด 10์ ์ด๋ด |
| 117 | + ํ๊ธ, ์๋ฌธ, ์ซ์ ์ด 10์ ์ด๋ด |
155 | 118 | </p>
|
156 | 119 | </>
|
157 | 120 | ) : (
|
158 |
| - <p className="semibold-16 text-grayscale-darkgray">[email protected]</p> |
| 121 | + <p className="semibold-16 text-grayscale-darkgray">{localStorage.getItem("email")}</p> |
159 | 122 | )}
|
160 | 123 | </div>
|
161 | 124 |
|
162 | 125 | <div className="w-full max-w-sm">
|
163 | 126 | <Button
|
164 | 127 | type="full"
|
165 |
| - buttonStyle={isNicknameEdit && isValid ? "blue" : "black"} |
| 128 | + buttonStyle={isUsernameEdit && isValid ? "blue" : "black"} |
166 | 129 | onClick={handleEditButtonClicked}
|
167 | 130 | >
|
168 | 131 | <EnterIcon className="fill-grayscale-white" />
|
169 |
| - {isNicknameEdit ? "๋๋ค์ ๋ณ๊ฒฝ ์๋ฃํ๊ธฐ" : "๋๋ค์ ๋ณ๊ฒฝํ๊ธฐ"} |
| 132 | + {isUsernameEdit ? "๋๋ค์ ๋ณ๊ฒฝ ์๋ฃํ๊ธฐ" : "๋๋ค์ ๋ณ๊ฒฝํ๊ธฐ"} |
170 | 133 | </Button>
|
171 | 134 | </div>
|
172 | 135 |
|
173 | 136 | <h3 className="mt-12 semibold-32">๊ฐ์ ๋ค์๋ณด๊ธฐ</h3>
|
174 |
| - <div className="flex flex-col w-full gap-6"> |
175 |
| - {DUMMY_DATA.map((value, index) => ( |
176 |
| - <ReplayLectureCard |
177 |
| - key={index} |
178 |
| - profileImage={value.profileImage} |
179 |
| - date={value.date} |
180 |
| - duration={value.duration} |
181 |
| - user={value.user} |
182 |
| - title={value.title} |
183 |
| - description={value.description} |
184 |
| - /> |
185 |
| - ))} |
| 137 | + <div className="flex flex-col w-full gap-6 items-center"> |
| 138 | + {lectureList.length ? ( |
| 139 | + lectureList.map((value, index) => ( |
| 140 | + <ReplayLectureCard |
| 141 | + key={index} |
| 142 | + date={value.date} |
| 143 | + duration={value.duration} |
| 144 | + user={value.user} |
| 145 | + title={value.title} |
| 146 | + description={value.description} |
| 147 | + onClick={() => navigate("/")} |
| 148 | + /> |
| 149 | + )) |
| 150 | + ) : ( |
| 151 | + <> |
| 152 | + <img className="max-w-sm w-full" src={SubLogoOriginal} /> |
| 153 | + <p className="semibold-16 text-grayscale-darkgray -mb-4">์์ง ์๊ฐํ ๊ฐ์๊ฐ ์กด์ฌํ์ง ์์์.</p> |
| 154 | + <p className="semibold-16 text-grayscale-darkgray mb-6">์๋ก์ด ๊ฐ์๋ฅผ ์๊ฐํ๋ฌ ๊ฐ๋ณผ๊น์?</p> |
| 155 | + </> |
| 156 | + )} |
186 | 157 | </div>
|
187 | 158 | </section>
|
188 | 159 | </div>
|
|
0 commit comments