Skip to content

Commit

Permalink
feat: writingPage 기능 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
1two13 committed Jun 28, 2023
1 parent 85e0cfe commit 2d5b3bb
Showing 1 changed file with 147 additions and 54 deletions.
201 changes: 147 additions & 54 deletions src/pages/WritingPage.jsx
Original file line number Diff line number Diff line change
@@ -1,79 +1,168 @@
import React, { useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import Select from 'react-select';

import LongButton from '../components/common/LongButton';
import Input from '../components/writingPage/Input';
import BackButton from '../components/common/navBar/BackButton';
import { writingSlice } from '../redux/slices/writingSlice';

import {
ADD_IMAGE,
ARTICLE_TITLE,
CATEGORY,
TOTAL_AMOUNT,
MAXIMUM_PEOPLE,
DESIRED_PLACE,
PLEASE_WRITE_TEXT,
DONE,
} from '../static/constants';
import { ADD_IMAGE, ARTICLE_TITLE, TOTAL_AMOUNT, MAXIMUM_PEOPLE, PLEASE_WRITE_TEXT, DONE } from '../static/constants';

function WritingPage() {
const options = [
// TODO: 하드코딩된 값 constants로 추후 변경 예정
{ value: '전체', label: '전체' },
{ value: '과일', label: '과일' },
{ value: '채소', label: '채소' },
{ value: '쌀/잡곡/견과', label: '쌀/잡곡/견과' },
{ value: '정육/계란류', label: '정육/계란류' },
{ value: '수산물/건해산', label: '수산물/건해산' },
{ value: '우유/유제품', label: '우유/유제품' },
{ value: '김치/반찬/델리', label: '김치/반찬/델리' },
{ value: '생수/음료/주류', label: '생수/음료/주류' },
{ value: '정육/계란류', label: '정육/계란류' },
{ value: '커피/차/원두', label: '커피/차/원두' },
{ value: '면류/통조림', label: '면류/통조림' },
{ value: '양념/오일', label: '양념/오일' },
{ value: '과자/간식', label: '과자/간식' },
{ value: '베이커리/잼', label: '베이커리/잼' },
{ value: '친환경/유기농', label: '친환경/유기농' },
];
const min = 1;
const max = 4;

const imgRef = useRef(null);
const [count, setCount] = useState(1);
const navigate = useNavigate();
const dispatch = useDispatch();
const title = useSelector((state) => state.writing.title);
const imageUrl = useSelector((state) => state.writing.imageUrl);
const totalAmount = useSelector((state) => state.writing.totalAmount);
const textarea = useSelector((state) => state.writing.textarea);

const [count, setCount] = useState(min);
const [selectedCategory, setSelectedCategory] = useState(options[0]);

const addImages = () => imgRef.current?.click();
const addImagesHandler = (e) => {};
const removeImage = () => dispatch(writingSlice.actions.setImageUrl(null));
const onChangeImage = (e) => {
const files = e.target.files[0];
const reader = new FileReader();

if (files === undefined) return;

reader.readAsDataURL(files);
reader.onload = () => {
dispatch(writingSlice.actions.setImageUrl(reader.result));
};
};

const onChangeTitle = (e) => {
dispatch(writingSlice.actions.setTitle(e.target.value));
};

const onChangeCategory = (e) => {
const selectedValue = e.value;
setSelectedCategory(selectedValue);
dispatch(writingSlice.actions.setCategory(selectedValue));
};

const onChangeTotalAmount = (e) => {
const totalAmount = e.target.value;

if (!/^[0-9]*$/.test(totalAmount)) e.target.value = '';
else dispatch(writingSlice.actions.setTotalAmount(totalAmount));
};

const decreaseCount = () => {
const newCount = Math.max(count - 1, min);
setCount(newCount);
dispatch(writingSlice.actions.setMaxPeople(newCount));
};
const increaseCount = () => {
const newCount = Math.min(count + 1, max);
setCount(newCount);
dispatch(writingSlice.actions.setMaxPeople(newCount));
};

const onChangeTextarea = (e) => {
dispatch(writingSlice.actions.setTextarea(e.target.value));
};

const onclickDoneButton = () => navigate('/posts');

return (
<div>
<div class="flex items-center justify-center w-[100%] h-[340px] bg-gray cursor-pointer" onClick={addImages}>
<button class="flex flex-col items-center text-[13px] text-darkGray">
<input type="file" class="hidden" multiple accept="image/png, image/jpg, image/jpeg" ref={imgRef} />
<img alt="" class="w-[390px] h-[340px] z-[50]" />
<div class="flex flex-col absolute top-[142px]">
<svg
width="76"
height="68"
viewBox="0 0 76 68"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class="mb-[20px]"
>
<div className="mt-[47px]">
<BackButton />
<div className="flex justify-center">
<div
className="flex items-center justify-center w-[360px] h-[238px] mt-[11px] bg-gray rounded-[15px] cursor-pointer"
onClick={addImages}
onChange={onChangeImage}
>
<button className="flex flex-col items-center text-[13px] text-darkGray">
<input type="file" className="hidden" multiple accept="image/png, image/jpg, image/jpeg" ref={imgRef} />
{imageUrl && <img alt="" src={imageUrl} className="w-[360px] h-[238px] rounded-[15px] z-[50]" />}
<div className="flex flex-col top-[177px] absolute">
<svg
width="76"
height="68"
viewBox="0 0 76 68"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mb-[20px]"
>
<path
d="M8 8H19.25L26.75 0.5H49.25L56.75 8H68C69.9891 8 71.8968 8.79018 73.3033 10.1967C74.7098 11.6032 75.5 13.5109 75.5 15.5V60.5C75.5 62.4891 74.7098 64.3968 73.3033 65.8033C71.8968 67.2098 69.9891 68 68 68H8C6.01088 68 4.10322 67.2098 2.6967 65.8033C1.29018 64.3968 0.5 62.4891 0.5 60.5V15.5C0.5 13.5109 1.29018 11.6032 2.6967 10.1967C4.10322 8.79018 6.01088 8 8 8ZM38 19.25C33.0272 19.25 28.2581 21.2254 24.7417 24.7417C21.2254 28.2581 19.25 33.0272 19.25 38C19.25 42.9728 21.2254 47.7419 24.7417 51.2583C28.2581 54.7746 33.0272 56.75 38 56.75C42.9728 56.75 47.7419 54.7746 51.2583 51.2583C54.7746 47.7419 56.75 42.9728 56.75 38C56.75 33.0272 54.7746 28.2581 51.2583 24.7417C47.7419 21.2254 42.9728 19.25 38 19.25ZM38 26.75C40.9837 26.75 43.8452 27.9353 45.955 30.045C48.0647 32.1548 49.25 35.0163 49.25 38C49.25 40.9837 48.0647 43.8452 45.955 45.955C43.8452 48.0647 40.9837 49.25 38 49.25C35.0163 49.25 32.1548 48.0647 30.045 45.955C27.9353 43.8452 26.75 40.9837 26.75 38C26.75 35.0163 27.9353 32.1548 30.045 30.045C32.1548 27.9353 35.0163 26.75 38 26.75Z"
fill="#9D9D9D"
/>
</svg>
{ADD_IMAGE}
</div>
</button>
</div>
</div>

<div>
{imageUrl ? (
<button
onClick={removeImage}
className="flex items-center justify-center h-[32px] w-[32px] top-[114px] ml-[331px] rounded-full bg-[black] opacity-[60%] absolute z-[999]"
>
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M8 8H19.25L26.75 0.5H49.25L56.75 8H68C69.9891 8 71.8968 8.79018 73.3033 10.1967C74.7098 11.6032 75.5 13.5109 75.5 15.5V60.5C75.5 62.4891 74.7098 64.3968 73.3033 65.8033C71.8968 67.2098 69.9891 68 68 68H8C6.01088 68 4.10322 67.2098 2.6967 65.8033C1.29018 64.3968 0.5 62.4891 0.5 60.5V15.5C0.5 13.5109 1.29018 11.6032 2.6967 10.1967C4.10322 8.79018 6.01088 8 8 8ZM38 19.25C33.0272 19.25 28.2581 21.2254 24.7417 24.7417C21.2254 28.2581 19.25 33.0272 19.25 38C19.25 42.9728 21.2254 47.7419 24.7417 51.2583C28.2581 54.7746 33.0272 56.75 38 56.75C42.9728 56.75 47.7419 54.7746 51.2583 51.2583C54.7746 47.7419 56.75 42.9728 56.75 38C56.75 33.0272 54.7746 28.2581 51.2583 24.7417C47.7419 21.2254 42.9728 19.25 38 19.25ZM38 26.75C40.9837 26.75 43.8452 27.9353 45.955 30.045C48.0647 32.1548 49.25 35.0163 49.25 38C49.25 40.9837 48.0647 43.8452 45.955 45.955C43.8452 48.0647 40.9837 49.25 38 49.25C35.0163 49.25 32.1548 48.0647 30.045 45.955C27.9353 43.8452 26.75 40.9837 26.75 38C26.75 35.0163 27.9353 32.1548 30.045 30.045C32.1548 27.9353 35.0163 26.75 38 26.75Z"
fill="#9D9D9D"
d="M13.6857 12.6573L8.02886 7.00048L13.6857 1.34362C13.8221 1.20723 13.8987 1.02225 13.8987 0.829365C13.8987 0.63648 13.8221 0.451495 13.6857 0.315104C13.5493 0.178715 13.3643 0.102091 13.1715 0.102091C12.9786 0.102091 12.7936 0.178715 12.6572 0.315105L7.00034 5.97196L1.34348 0.315104C1.20709 0.178714 1.02211 0.102091 0.829224 0.102091C0.636339 0.102091 0.451354 0.178714 0.314964 0.315104C0.245591 0.379402 0.190806 0.457824 0.154302 0.545084C0.117798 0.632344 0.100422 0.726415 0.103345 0.820958C0.10627 0.915501 0.129426 1.00832 0.171253 1.09316C0.21308 1.17799 0.272605 1.25288 0.34582 1.31277L6.00267 6.96962L0.314964 12.6573C0.178574 12.7937 0.101951 12.9787 0.101951 13.1716C0.10195 13.3645 0.178574 13.5495 0.314964 13.6859C0.451355 13.8222 0.636339 13.8989 0.829224 13.8989C1.02211 13.8989 1.20709 13.8222 1.34348 13.6859L7.00034 8.029L12.6572 13.6859C12.7936 13.8222 12.9786 13.8989 13.1715 13.8989C13.3643 13.8989 13.5493 13.8222 13.6857 13.6859C13.8221 13.5495 13.8987 13.3645 13.8987 13.1716C13.8987 12.9787 13.8221 12.7937 13.6857 12.6573Z"
fill="white"
/>
</svg>
{ADD_IMAGE}
</div>
</button>
</button>
) : (
''
)}
</div>
{/* TODO: X 버튼 클릭했을 때 사진 제거 */}
<button class="flex items-center justify-center h-[44px] w-[44px] top-[47px] ml-[15px] rounded-full bg-white drop-shadow-md absolute z-[999]">
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M19.193 17.7784L11.4148 10.0002L19.193 2.22206C19.3805 2.03452 19.4859 1.78017 19.4859 1.51495C19.4859 1.24973 19.3805 0.995378 19.193 0.807842C19.0054 0.620305 18.7511 0.514948 18.4859 0.514948C18.2206 0.514948 17.9663 0.620305 17.7788 0.807842L10.0006 8.58602L2.22241 0.807842C2.03487 0.620305 1.78052 0.514948 1.5153 0.514948C1.25009 0.514948 0.995734 0.620305 0.808197 0.807842C0.712809 0.896251 0.63748 1.00408 0.587287 1.12406C0.537093 1.24405 0.513201 1.37339 0.517222 1.50339C0.521242 1.63339 0.553082 1.76101 0.610594 1.87766C0.668106 1.99431 0.749954 2.09728 0.850623 2.17963L8.6288 9.9578L0.808197 17.7784C0.620661 17.9659 0.515303 18.2203 0.515303 18.4855C0.515303 18.7507 0.620661 19.0051 0.808197 19.1926C0.995734 19.3802 1.25009 19.4855 1.5153 19.4855C1.78052 19.4855 2.03487 19.3802 2.22241 19.1926L10.0006 11.4144L17.7788 19.1926C17.9663 19.3802 18.2207 19.4855 18.4859 19.4855C18.7511 19.4855 19.0054 19.3802 19.193 19.1926C19.3805 19.0051 19.4859 18.7507 19.4859 18.4855C19.4859 18.2203 19.3805 17.9659 19.193 17.7784Z"
fill="black"
/>
</svg>
</button>

<Input placeholder={ARTICLE_TITLE} />
<div class="py-[15px] mx-[15px] text-[13px] text-darkGray border-b-[0.5px] border-gray">
<button>{CATEGORY}</button>

<Input placeholder={ARTICLE_TITLE} onChange={onChangeTitle} />

<div className="mx-[15px] py-[15px] text-red border-b-[0.5px] border-gray">
<Select defaultValue={selectedCategory} options={options} onChange={onChangeCategory} />
</div>
<Input placeholder={TOTAL_AMOUNT} />

<div class="flex justify-between py-[15px] mx-[15px] text-[13px] text-darkGray border-b-[0.5px] border-gray">
<div>{MAXIMUM_PEOPLE}</div>
<div class="flex">
<button>
<Input placeholder={TOTAL_AMOUNT} onChange={onChangeTotalAmount} />

<div className="flex justify-between py-[15px] mx-[15px] text-[13px] text-darkGray border-b-[0.5px] border-gray">
<div className="flex items-center">{MAXIMUM_PEOPLE}</div>
<div className="flex">
<button onClick={decreaseCount}>
<svg width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M22.9167 0H2.08333C1.5308 0 1.00089 0.219493 0.610194 0.610194C0.219493 1.00089 0 1.5308 0 2.08333V22.9167C0 23.4692 0.219493 23.9991 0.610194 24.3898C1.00089 24.7805 1.5308 25 2.08333 25H22.9167C23.4692 25 23.9991 24.7805 24.3898 24.3898C24.7805 23.9991 25 23.4692 25 22.9167V2.08333C25 1.5308 24.7805 1.00089 24.3898 0.610194C23.9991 0.219493 23.4692 0 22.9167 0ZM19.7917 13.5417H5.20833C4.93207 13.5417 4.66711 13.4319 4.47176 13.2366C4.27641 13.0412 4.16667 12.7763 4.16667 12.5C4.16667 12.2237 4.27641 11.9588 4.47176 11.7634C4.66711 11.5681 4.93207 11.4583 5.20833 11.4583H19.7917C20.0679 11.4583 20.3329 11.5681 20.5282 11.7634C20.7236 11.9588 20.8333 12.2237 20.8333 12.5C20.8333 12.7763 20.7236 13.0412 20.5282 13.2366C20.3329 13.4319 20.0679 13.5417 19.7917 13.5417Z"
fill="#A4A4A4"
/>
</svg>
</button>
<div class="flex justify-center items-center w-[63px] mx-[10px]">{count}</div>
<button>
<div className="flex justify-center items-center w-[63px] mx-[10px]">{count}</div>
<button onClick={increaseCount}>
<svg width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M22.9167 0H2.08333C1.5308 0 1.00089 0.219493 0.610194 0.610194C0.219493 1.00089 0 1.5308 0 2.08333V22.9167C0 23.4692 0.219493 23.9991 0.610194 24.3898C1.00089 24.7805 1.5308 25 2.08333 25H22.9167C23.4692 25 23.9991 24.7805 24.3898 24.3898C24.7805 23.9991 25 23.4692 25 22.9167V2.08333C25 1.5308 24.7805 1.00089 24.3898 0.610194C23.9991 0.219493 23.4692 0 22.9167 0ZM19.7917 13.5417H13.5417V19.7917C13.5417 20.0679 13.4319 20.3329 13.2366 20.5282C13.0412 20.7236 12.7763 20.8333 12.5 20.8333C12.2237 20.8333 11.9588 20.7236 11.7634 20.5282C11.5681 20.3329 11.4583 20.0679 11.4583 19.7917V13.5417H5.20833C4.93207 13.5417 4.66711 13.4319 4.47176 13.2366C4.27641 13.0412 4.16667 12.7763 4.16667 12.5C4.16667 12.2237 4.27641 11.9588 4.47176 11.7634C4.66711 11.5681 4.93207 11.4583 5.20833 11.4583H11.4583V5.20833C11.4583 4.93207 11.5681 4.66711 11.7634 4.47176C11.9588 4.27641 12.2237 4.16667 12.5 4.16667C12.7763 4.16667 13.0412 4.27641 13.2366 4.47176C13.4319 4.66711 13.5417 4.93207 13.5417 5.20833V11.4583H19.7917C20.0679 11.4583 20.3329 11.5681 20.5282 11.7634C20.7236 11.9588 20.8333 12.2237 20.8333 12.5C20.8333 12.7763 20.7236 13.0412 20.5282 13.2366C20.3329 13.4319 20.0679 13.5417 19.7917 13.5417Z"
Expand All @@ -84,13 +173,17 @@ function WritingPage() {
</div>
</div>

<Input placeholder={DESIRED_PLACE} />
<textarea
placeholder={PLEASE_WRITE_TEXT}
class="w-[92%] h-[140px] py-[20px] mx-[15px] focus:outline-none text-[13px] text-darkGray"
onChange={onChangeTextarea}
className="w-[92%] h-[150px] py-[20px] mx-[15px] focus:outline-none text-[13px] text-darkGray"
/>

<LongButton contents={DONE} />
{!title || totalAmount === 0 || !textarea ? (
<LongButton contents={DONE} className="disabled" background={'#CCCCCC'} customStyle={'disabled'} />
) : (
<LongButton contents={DONE} onClick={onclickDoneButton} />
)}
</div>
);
}
Expand Down

0 comments on commit 2d5b3bb

Please sign in to comment.