| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- 'use client';
- import './style.scss';
- import Link from 'next/link';
- import Image from 'next/image';
- import { useState, useEffect } from 'react';
- import { useMemberContext } from '@/contexts/memberProvider';
- import { fetchChangePhoto } from '@/lib/api/account';
- export default function ChangePhoto()
- {
- const { member, setMember } = useMemberContext();
- const [error, setError] = useState<string>('');
- const [newPhoto, setNewPhoto] = useState<File|null>(null);
- const [preview, setPreview] = useState<string|null>(null);
- const [remove, setRemove] = useState<boolean>(false);
- useEffect(() => {
- if (error) {
- alert(error);
- setError('');
- }
- }, [error]);
- const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
- e.preventDefault();
- if (!member) {
- return;
- }
- if (!newPhoto && !remove) {
- return setError('사진을 선택하세요.');
- }
- fetchChangePhoto(newPhoto).then((res) => {
- if (!res.ok) {
- throw new Error(res.message!);
- }
- member.photo = (res.data?.photoURL || null);
- setMember(member);
- localStorage.setItem('member', JSON.stringify(member));
- alert("사진이 변경되었습니다.");
- }).catch(err => {
- handleRemove();
- setError(err.message);
- }).finally(() => {
- setRemove(false);
- setNewPhoto(null);
- setPreview(null);
- });
- }
- const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
- if (e.target.files && e.target.files[0]) {
- const selectedFile = e.target.files[0];
- setNewPhoto(selectedFile);
- setRemove(false);
- // 이미지 미리보기
- const reader = new FileReader();
- reader.onloadend = () => setPreview(reader.result as string);
- reader.readAsDataURL(selectedFile);
- }
- };
- const handleRemove = () => {
- setNewPhoto(null);
- setPreview(null);
- setRemove(true);
- const fileInput = document.getElementById("photo") as HTMLInputElement;
- if (fileInput) {
- fileInput.value = ""; // 파일 선택 초기화
- }
- };
- return (
- <div id="changePhoto">
- <h1>회원 사진</h1>
- <form id="fChangePhoto" method="post" acceptCharset="utf-8" autoComplete="off" onSubmit={handleSubmit}>
- <table className="table-auto max-xl:w-full lg:w-[600px]">
- <caption>
- 커뮤니티 프로필에 대표 사진을 설정할 수 있습니다.
- </caption>
- <colgroup>
- <col width="140px"/>
- <col width="*"/>
- </colgroup>
- <tbody>
- <tr>
- <th>
- <figure>
- {preview ?
- <Image src={preview} alt="미리보기" width={140} height={140} layout="responsive" style={{objectFit: "cover"}} />
- :
- (member.photo && !remove) ?
- <Image src={member.photo} alt={member.email} width={140} height={140} style={{objectFit: "cover"}} unoptimized={true} />
- :
- <Image src="/resources/thumb.gif" alt="기본 사진" width={140} height={140} style={{objectFit: "cover"}} />
- }
- </figure>
- </th>
- <td>
- <div className="flex justify-start gap-2">
- <label htmlFor="photo" className="btn btn-default">사진 변경</label>
- <input type="file" id="photo" accept="image/jpg,image/jpeg,image/png,image/gif" hidden onChange={handleChange} />
- {(preview || member?.photo) &&
- <button type="button" className="btn btn-default" onClick={handleRemove}>삭제</button>
- }
- </div>
- <p className="mt-3">
- 98x98 크기 이상, 4MB 이하의 사진이 권장됩니다. 이미지 파일을 사용하세요. 사진이 {process.env.NEXT_PUBLIC_SITE_NAME} 커뮤니티 가이드를 준수해야 합니다.
- </p>
- </td>
- </tr>
- </tbody>
- <tfoot>
- <tr>
- <td colSpan={2}>
- <div className="flex justify-center gap-2">
- <button type="submit" className="btn btn-submit">확인</button>
- <Link href="/profile" className="btn btn-default">취소</Link>
- </div>
- </td>
- </tr>
- </tfoot>
- </table>
- </form>
- </div>
- );
- }
|