| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- 'use client';
- import './style.scss';
- import Link from 'next/link';
- import { useState, useEffect } from 'react';
- import { useConfigContext } from '@/contexts/configProvider';
- import { useMemberContext } from '@/contexts/memberProvider';
- import { ChangeIntroRequest } from '@/dtos/request/account';
- import { fetchApi, throwError } from '@/lib/utils/client';
- import Loading from '@/app/component/Loading';
- import Editor from '@/app/component/Editor';
- export default function ChangeIntro()
- {
- const config = useConfigContext();
- const { member, setMember } = useMemberContext();
- const [error, setError] = useState<string>('');
- const [loading, setLoading] = useState<boolean>(false);
- const [newIntro, setNewIntro] = useState<string|null>('');
- useEffect(() => {
- if (error) {
- alert(error);
- setError('');
- }
- }, [error]);
- useEffect(() => {
- if (member?.intro && !newIntro) {
- const intro = member.intro.replace(/<img\b[^>]*?\bsrc=[''](\/[^'']*)['']/gi, (match, srcPath) => {
- return match.replace(srcPath, process.env.API_URL + srcPath);
- });
- setNewIntro(intro);
- }
- }, [member, newIntro]);
- const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
- e.preventDefault();
- if (!member) {
- return;
- }
- setLoading(true);
- fetchApi('/api/mypage/intro', {
- method: 'POST',
- body: { Intro: newIntro } as ChangeIntroRequest
- }).then((res) => {
- throwError(res);
- member.intro = newIntro;
- setMember(member);
- setNewIntro(newIntro);
- localStorage.setItem('member', JSON.stringify(member));
- alert('자기소개가 변경되었습니다.');
- }).catch(err => {
- setError(err.message);
- setNewIntro(member.intro);
- }).finally(() => {
- setLoading(false);
- });
- }
- const handleDelete = async () => {
- if (confirm("자기소개를 삭제하시겠습니까?")) {
- if (!member || !member.intro) {
- return;
- }
- setLoading(true);
- fetchApi('/api/mypage/intro', { method: 'DELETE' }).then((res) => {
- throwError(res);
- member.intro = null;
- setMember(member);
- localStorage.setItem('member', JSON.stringify(member));
- alert("자기소개가 삭제되었습니다.");
- }).catch(err => {
- setError(err.message);
- }).finally(() => {
- setLoading(false);
- setNewIntro('');
- });
- }
- };
- return (
- <>
- <div id='changeIntro'>
- { loading && <Loading /> }
- <h1>자기소개 변경</h1>
- <form method='post' acceptCharset='utf-8' autoComplete='off' onSubmit={handleSubmit}>
- <table className='table-auto max-xl:w-full xl:w-[800px]'>
- <caption>
- 커뮤니티 프로필에 표시되는 자기소개를 설정할 수 있습니다.
- </caption>
- <tbody>
- <tr>
- <td>
- <Editor data={newIntro ?? ''} onChange={setNewIntro} />
- </td>
- </tr>
- </tbody>
- <tfoot>
- <tr>
- <td colSpan={3}>
- <div className='flex justify-center gap-2'>
- <button type='submit' className='btn btn-submit'>확인</button>
- { member?.intro && (
- <button type="button" className="btn btn-delete" onClick={handleDelete}>삭제</button>
- )}
- <Link href='/profile' className='btn btn-default'>취소</Link>
- </div>
- </td>
- </tr>
- </tfoot>
- </table>
- </form>
- <br />
- <dl className='max-xl:w-full xl:w-[800px]'>
- <dt hidden> </dt>
- <dd>
- <ol>
- <li>자기소개는 최대 1000자 이내로 입력 가능합니다.</li>
- <li>부적절한 내용은 별도의 고지 없이 삭제될 수 있습니다.</li>
- {config.account.changeIntroDay > 0 && <li>한마디 변경 주기는 {config.account.changeIntroDay}일입니다.</li>}
- </ol>
- </dd>
- </dl>
- </div>
- </>
- );
- }
|