profile.tsx 5.54 KB
Newer Older
Yoon, Daeki's avatar
Yoon, Daeki committed
1
import React, { ChangeEvent, FormEvent, useEffect, useState } from "react";
2
3
import { Profile } from "../types";
import { profileApi } from "../apis";
Kim, MinGyu's avatar
Kim, MinGyu committed
4
import { useAuth } from "../auth/auth.context";
Kim, MinGyu's avatar
Kim, MinGyu committed
5
import { Link } from "react-router-dom";
Kim, MinGyu's avatar
Kim, MinGyu committed
6
7
8

export default function Profile() {
  // 로컬 저장소에는 로그인 여부만 저장
9
  const [email, setEmail] = useState("");
Yoon, Daeki's avatar
Yoon, Daeki committed
10
11
12
13
14
  const [profile, setProfile] = useState<{
    name: string;
    avatar: File | null;
  }>({ name: "", avatar: null });
  const [avatarUrl, setAvatarUrl] = useState("");
15
  const [imageSrc, setImageSrc] = useState("");
Kim, MinGyu's avatar
Kim, MinGyu committed
16
  const { logout } = useAuth();
Kim, MinGyu's avatar
Kim, MinGyu committed
17

Yoon, Daeki's avatar
Yoon, Daeki committed
18
19
20
21
22
23
24
25
26
  const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
    const { name, value, files } = e.target;
    console.log("name", name, "value", value);
    if (files) {
      setProfile({ ...profile, [name]: files[0] });
      showImage(files[0]);
    } else {
      setProfile({ ...profile, [name]: value });
    }
27
28
  };

Yoon, Daeki's avatar
Yoon, Daeki committed
29
  const showImage = (blob: Blob) => {
30
    const reader = new FileReader();
Yoon, Daeki's avatar
Yoon, Daeki committed
31
    reader.readAsDataURL(blob);
32
33
    reader.onload = (data) => {
      if (typeof data.target?.result === "string") {
Yoon, Daeki's avatar
Yoon, Daeki committed
34
        // console.log(data.target?.result);
35
36
37
38
39
        setImageSrc(data.target?.result);
      }
    };
  };

Yoon, Daeki's avatar
Yoon, Daeki committed
40
  const handleSubmit = async (e: FormEvent) => {
Kim, MinGyu's avatar
Kim, MinGyu committed
41
    e.preventDefault();
Yoon, Daeki's avatar
Yoon, Daeki committed
42
    console.log("profile in submit", profile);
43
    const formdata = new FormData();
Yoon, Daeki's avatar
Yoon, Daeki committed
44
    profile.avatar && formdata.append("avatar", profile.avatar);
45
46

    console.log(profile.avatar);
Yoon, Daeki's avatar
Yoon, Daeki committed
47
48
49
    formdata.append("name", profile.name);
    console.log("form data", formdata.get("avatar"));
    profileApi.profileUpload(formdata);
Kim, MinGyu's avatar
Kim, MinGyu committed
50
51
  };

Yoon, Daeki's avatar
Yoon, Daeki committed
52
  const onDelete = async () => {
Kim, MinGyu's avatar
Kim, MinGyu committed
53
    if (confirm("삭제하시겠습니까?") == true) {
Yoon, Daeki's avatar
Yoon, Daeki committed
54
55
      await profileApi.deleteUser();
      await logout();
Kim, MinGyu's avatar
Kim, MinGyu committed
56
    }
Kim, MinGyu's avatar
Kim, MinGyu committed
57
58
  };

Kim, MinGyu's avatar
Kim, MinGyu committed
59
  useEffect(() => {
Yoon, Daeki's avatar
Yoon, Daeki committed
60
61
62
63
    const getProfile = async () => {
      const user: Profile = await profileApi.profile();
      console.log("user in effect", user);
      setEmail(user.email);
64
      setAvatarUrl(user.avatar?.newfilename);
Yoon, Daeki's avatar
Yoon, Daeki committed
65
66
67
      setProfile({ ...profile, name: user.name });
    };
    getProfile();
Kim, MinGyu's avatar
Kim, MinGyu committed
68
69
70
  }, []);

  return (
Lee Soobeom's avatar
Lee Soobeom committed
71
72
73
74
75
76
77
78
79
80
81
82
    <div>
      <div className="grid bg-white rounded shadow-lg mb-5">
        <form className="mx-24 " onSubmit={handleSubmit}>
          <div className=" mt-7 text-2xl">프로필 수정</div>
          <div className=" mt-10 border-0 border-y-2 border-gray-400">
            <div className="flex h-20">
              <div className="w-24  border-0 border-r-2 bg-gray-100 grid place-items-center whitespace-nowrap">
                Email
              </div>
              <div className=" grid place-items-center px-4 whitespace-nowrap">
                {email}
              </div>
83
            </div>
Lee Soobeom's avatar
Lee Soobeom committed
84
85
86
87
88
89
90
91
            <div className="flex border-0 border-t-2">
              <div className="w-24 border-0 border-r-2 bg-gray-100 grid place-items-center whitespace-nowrap">
                사진
              </div>
              <div className="flex  py-4 ">
                <div className="">
                  <div className="overflow-hidden w-28 h-28 rounded-full border-2 mx-3 mb-3">
                    {imageSrc ? (
Kim, MinGyu's avatar
Kim, MinGyu committed
92
                      <img
Lee Soobeom's avatar
Lee Soobeom committed
93
                        src={imageSrc}
Kim, MinGyu's avatar
Kim, MinGyu committed
94
95
                        className="object-cover object-center h-full"
                      />
Lee Soobeom's avatar
Lee Soobeom committed
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
                    ) : (
                      avatarUrl && (
                        <img
                          src={"http://localhost:3000/images/" + avatarUrl}
                          className="object-cover object-center h-full"
                        />
                      )
                    )}
                  </div>
                  <input
                    type="file"
                    name="avatar"
                    id="avatar"
                    className="hidden"
                    onChange={handleChange}
                  ></input>
                  <label
                    htmlFor="avatar"
                    className="border-2 m-5 whitespace-nowrap "
                  >
                    이미지 선택
                  </label>
                </div>
                <div className="pl-10 flex place-self-center text-gray-400 text-sm whitespace-nowrap">
                  {"<새로운 이미지를 넣어보세요!>"}
Kim, MinGyu's avatar
Kim, MinGyu committed
121
                </div>
Kim, MinGyu's avatar
Kim, MinGyu committed
122
              </div>
123
            </div>
Lee Soobeom's avatar
Lee Soobeom committed
124
125
126
127
128
129
130
131
132
133
            <div className="flex border-0 border-t-2 h-20">
              <div className="w-24 border-0 border-r-2 bg-gray-100 grid place-items-center whitespace-nowrap">
                이름
              </div>
              <input
                name="name"
                placeholder={profile.name}
                className=" placeholder:text-black my-6 ml-5 border-2 "
                onChange={handleChange}
              />
134
            </div>
Kim, MinGyu's avatar
Kim, MinGyu committed
135
          </div>
Lee Soobeom's avatar
Lee Soobeom committed
136
137
138
139
140
141
142
          <div className="flex mb-5 justify-center gap-x-3">
            <button
              onClick={handleSubmit}
              className=" mt-5 h-12 w-1/5 border-2 border-blue-400 text-lg  place-self-center whitespace-nowrap"
            >
              저장하기
            </button>
Kim, MinGyu's avatar
Kim, MinGyu committed
143

Lee Soobeom's avatar
Lee Soobeom committed
144
145
146
            <button className=" mt-5 h-12 w-1/5  text-lg border-2 border-orange-400 place-self-center whitespace-nowrap">
              <Link to="/">취소</Link>
            </button>
Kim, MinGyu's avatar
Kim, MinGyu committed
147

Lee Soobeom's avatar
Lee Soobeom committed
148
149
150
151
152
153
154
155
156
157
158
            <button
              type="button"
              onClick={onDelete}
              className=" mt-5 h-12 w-1/5  text-lg border-2 border-red-400 place-self-center whitespace-nowrap"
            >
              계정 삭제
            </button>
          </div>
        </form>
      </div>
      <div className="bg-lime-100 h-4" />
Kim, MinGyu's avatar
Kim, MinGyu committed
159
160
161
    </div>
  );
}