Skip to content

Commit

Permalink
[ merge into main ] 버그 수정
Browse files Browse the repository at this point in the history
[ merge into main ] 버그 수정
  • Loading branch information
NeatKYU authored Sep 16, 2023
2 parents c74d86e + 74e0fcd commit 311594d
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 40 deletions.
11 changes: 9 additions & 2 deletions src/components/card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,21 @@ interface CardProps {
}

export const Card = (props: CardProps) => {
const { title, goal, openMenu, startDate, endDate, className } = props;
const { title, goal, openMenu, onClick, startDate, endDate, className } = props;

const handleOpenMenu = (event: React.MouseEvent<HTMLDivElement>) => {
event.stopPropagation();
if (openMenu) openMenu(event);
};

return (
<div
className={`card w-full min-h-[128px] flex flex-col jusitfy-center px-[20px] py-[24px] bg-white ${className}`}
onClick={onClick}
>
<div className="flex justify-between mb-[8px]">
<Tag startDate={startDate} endDate={endDate} />
<div onClick={openMenu}>
<div onClick={handleOpenMenu}>
<More />
</div>
</div>
Expand Down
8 changes: 5 additions & 3 deletions src/components/common/input/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface InputProps {
rows?: number;
maxLength?: number;
isScroll?: boolean;
readOnly?: boolean;
}
export const Input = (props: InputProps) => {
const {
Expand All @@ -39,6 +40,7 @@ export const Input = (props: InputProps) => {
maxLength,
name,
isScroll,
readOnly,
} = props;
const textareaRef = useRef<HTMLTextAreaElement>(null);
const [isWrapperFocus, setIsWrapperFocus] = useState<boolean>(false);
Expand Down Expand Up @@ -103,6 +105,7 @@ export const Input = (props: InputProps) => {
name={name}
className="w-full outline-none body1"
inputMode={isInputModeNone ? 'none' : 'text'}
readOnly={readOnly}
/>
) : (
<textarea
Expand All @@ -117,12 +120,11 @@ export const Input = (props: InputProps) => {
rows={rows}
maxLength={maxLength}
inputMode={isInputModeNone ? 'none' : 'text'}
readOnly={readOnly}
/>
)}
{value && value.toString().length > 0 && !disabled ? (
<div onClick={handleDelete}>
<Delete />
</div>
<div onClick={handleDelete}>{!readOnly ? <Delete /> : null}</div>
) : null}
{Icon(icon)}
</div>
Expand Down
3 changes: 3 additions & 0 deletions src/components/layout/DefaultLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ export default function DefaultLayout({ children }: DefaultLayoutProp) {

const handleBack = () => {
if (location.pathname.startsWith('/nottodo/edit')) {
const params = new URLSearchParams(location.search);
if (params.get('state') === 'complete') return router(-1);

return setIsEditPopup(true);
} else {
return router(-1);
Expand Down
6 changes: 6 additions & 0 deletions src/constant/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ export const routeTitle = [
{ path: '/profile/contact', en: 'Contact Us', ko: '문의/건의하기', img: false },
{ path: '/badge', en: 'badge', ko: '뱃지', img: false },
];
export const completeJson = {
path: '/nottodo/edit/state',
en: 'complete',
ko: '종료된 낫투두',
img: false,
};

export const headerHiddenPaths = ['/login', '/profile', '/'];
export const headerBackPaths = [
Expand Down
42 changes: 27 additions & 15 deletions src/pages/home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ export default function HomePage() {
}, [selectedDate]);

useEffect(() => {
setMarkerDateObj(handleStatusModeration(moderations));
}, [moderations]);

const handleStatusModeration = (moderations: ModerationType[]) => {
const obj = moderations.reduce((acc, moderation) => {
const dateString = dateToyyyymmdd(new Date(moderation.regDtm), '-');
acc[dateString] = acc[dateString] || [];
Expand Down Expand Up @@ -86,23 +90,22 @@ export default function HomePage() {
return acc;
}, {} as MarkerDate);

setMarkerDateObj(markerObject);
}, [moderations]);
return markerObject;
};

const fetchNotToDos = async () => {
const data = await getNottodoList('in_close');
setFormattedNotToDoList(
data
.filter((item) => item.progressState === 'IN_PROGRESS')
.map((item) => ({
id: item.notToDoId,
title: item.notToDoText,
description: item.goal,
// TODO 성공일자 날짜 계산 해야함
success: diffDay(item.endDate, item.startDate),
totalDate: diffDay(new Date(), item.startDate),
})),
);
const formatDataPromise = data
.filter((item) => item.progressState === 'IN_PROGRESS')
.map(async (item) => ({
id: item.notToDoId,
title: item.notToDoText,
description: item.goal,
success: await getSuccessDay(item.notToDoId, item.endDate, item.startDate),
totalDate: diffDay(new Date(), item.startDate),
}));
const formatData = await Promise.all(formatDataPromise);
setFormattedNotToDoList(formatData);
};

const fetchModerationList = async () => {
Expand All @@ -129,7 +132,6 @@ export default function HomePage() {
const handleInputValue = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value);
if (e.target.value.length >= 4) {
console.log('warnnig false');
setInputWarning(false);
}
};
Expand All @@ -142,6 +144,16 @@ export default function HomePage() {
setInputValue('');
};

const getSuccessDay = async (id: number, startDate: string, endDate: string) => {
const list = await getModerationList(dateToyyyymmdd(new Date(endDate)), dateToyyyymmdd(new Date(startDate)));
if (list) {
const statusList = handleStatusModeration(list.filter((item) => item.notToDoId === id));
return Object.values(statusList).filter((status) => status === 'success').length;
} else {
return 0;
}
};

const handleSubmitRecord = async () => {
if (inputValue.length < 4) {
setInputWarning(true);
Expand Down
78 changes: 67 additions & 11 deletions src/pages/nottodo/NotTodoCreatePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,27 @@ import { diffDay, formatDateToString, dateToyyyymmdd } from '@/utils/datepicker'
import { Toast } from '@/components/toast/Toast';
import { createNottodo, editNottodo } from '@/api/nottodo';
import { useRecoilValue } from 'recoil';
import { currentNottodoState } from '@/recoil/nottodo/atom';
import { currentNottodoState, nottodoProps } from '@/recoil/nottodo/atom';

interface editPayload {
notToDoText: string;
startDate: string;
endDate: string;
goal: string;
cheerUpMsg1: string;
cheerUpMsg2: string;
cheerUpMsg3: string;
}

export default function NotTodoCreatePage() {
const router = useNavigate();
const params = useParams();
const today = new Date();
const endDateRef = useRef<HTMLInputElement>(null);
const [title, setTitle] = useState<string>('');
const [goal, setGoal] = useState<string>('');
const [startDate, setStartDate] = useState<Date>(new Date());
const [endDate, setEndDate] = useState<Date>(new Date());
const [startDate, setStartDate] = useState<Date>(new Date(today.getFullYear(), today.getMonth(), today.getDate()));
const [endDate, setEndDate] = useState<Date>(new Date(today.getFullYear(), today.getMonth(), today.getDate()));
const [inputStartDate, setInputStartDate] = useState<string>('');
const [inputEndDate, setInputEndDate] = useState<string>('');
const [message1, setMessage1] = useState<string>('');
Expand All @@ -30,11 +41,13 @@ export default function NotTodoCreatePage() {

const [titleHelpText, setTitleHelpText] = useState<string>('');
const [dateHelpText, setDateHelpText] = useState<string>('');
const [isComplete, setIsComplete] = useState<boolean>(false);

useEffect(() => {
if (params && params.id) {
setIsEditPage(true);
if (currentNottodo) {
setIsComplete(currentNottodo.progressState === 'COMPLETE');
setTitle(currentNottodo.notToDoText);
setStartDate(new Date(currentNottodo.startDate));
setEndDate(new Date(currentNottodo.endDate));
Expand Down Expand Up @@ -101,14 +114,20 @@ export default function NotTodoCreatePage() {
// 시작일, 종료일 계산
const startTime = startDate.getTime();
const endTime = endDate.getTime();

if (startTime > endTime) {
setDateHelpText('시작일이 종료일보다 늦을 수 없습니다');
return false;
}

// 100일 초과 여부 검사
const diff = endTime - startTime;
const dayTime = 1000 * 60 * 60 * 24;
// 1일 미만인지 검사
if (diff < dayTime) {
setDateHelpText('도전일은 1일 이상이 되어야 합니다.');
return false;
}
// 100일 초과 여부 검사
if (diff > dayTime * 100) {
setDateHelpText('100일 이상은 등록하실 수 없습니다');
return false;
Expand Down Expand Up @@ -181,10 +200,38 @@ export default function NotTodoCreatePage() {
}
};

const isEditing = (origin: nottodoProps | null, edit: editPayload) => {
if (origin) {
if (origin.notToDoText !== edit.notToDoText) return true;
if (origin.startDate !== edit.startDate) return true;
if (origin.endDate !== edit.endDate) return true;
if (origin.goal !== edit.goal) return true;
if (origin.cheerUpMessageList[0].content !== edit.cheerUpMsg1) return true;
if (origin.cheerUpMessageList[1].content !== edit.cheerUpMsg2) return true;
if (origin.cheerUpMessageList[2].content !== edit.cheerUpMsg3) return true;
return false;
} else {
return false;
}
};

const renderButton = (isEdit: boolean) => {
if (isEdit) {
const payload = {
notToDoText: title,
startDate: dateToyyyymmdd(startDate, '-'),
endDate: dateToyyyymmdd(endDate, '-'),
goal,
cheerUpMsg1: message1,
cheerUpMsg2: message2,
cheerUpMsg3: message3,
};
return (
<BottomButton variant="secondary" clickHandler={handleEdit}>
<BottomButton
variant="secondary"
disabled={!isEditing(currentNottodo, payload)}
clickHandler={handleEdit}
>
수정 완료
</BottomButton>
);
Expand Down Expand Up @@ -215,14 +262,15 @@ export default function NotTodoCreatePage() {
helperText={titleHelpText}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleTitle(e)}
placeHolder="ex. 저녁 먹은 후 야식 참기"
readOnly={isComplete}
/>
<div className="h-[60px] w-full" />
<div className="flex items-center mb-3">
<div className="w-[37px] h-[21px] flex justify-center items-center bg-primary rounded-xl caption1">
필수
</div>
<div className="title1 ml-2">언제까지 도전하시나요?</div>
<div className="title2 text-accent ml-auto">{diffDay(startDate, endDate) + 1}</div>
<div className="title2 text-accent ml-auto">{diffDay(startDate, endDate)}</div>
</div>
<div className="w-full flex items-center">
<Input
Expand All @@ -231,9 +279,10 @@ export default function NotTodoCreatePage() {
setValue={setInputStartDate}
isWarning={!!dateHelpText}
isInputModeNone
onFocus={() => handleFocus('start')}
onFocus={!isComplete ? () => handleFocus('start') : () => null}
onChange={() => null}
placeHolder="시작일 입력"
readOnly={isComplete}
/>
<div className="mx-3 body1 text-gray-500">~</div>
<Input
Expand All @@ -243,9 +292,10 @@ export default function NotTodoCreatePage() {
setValue={setInputEndDate}
isWarning={!!dateHelpText}
isInputModeNone
onFocus={() => handleFocus('end')}
onFocus={!isComplete ? () => handleFocus('end') : () => null}
onChange={() => null}
placeHolder="종료일 입력"
readOnly={isComplete}
/>
</div>
{dateHelpText ? <div className="mt-1 title3 text-negative">{dateHelpText}</div> : null}
Expand Down Expand Up @@ -286,6 +336,7 @@ export default function NotTodoCreatePage() {
setValue={setGoal}
onChange={(e) => setGoal(e.target.value)}
placeHolder="ex. 3kg 감량하기"
readOnly={isComplete}
/>
<div className="body2 text-gray-600 mt-2">목표가 명확할수록 성공 확률이 높아져요!</div>
<div className="h-[60px] w-full" />
Expand All @@ -303,6 +354,7 @@ export default function NotTodoCreatePage() {
placeHolder="절제할 나를 응원할 메시지를 입력해주세요."
rows={1}
maxLength={100}
readOnly={isComplete}
/>
<Input
type="textarea"
Expand All @@ -313,6 +365,7 @@ export default function NotTodoCreatePage() {
placeHolder="절제할 나를 응원할 메시지를 입력해주세요."
rows={1}
maxLength={100}
readOnly={isComplete}
/>
<Input
type="textarea"
Expand All @@ -323,15 +376,18 @@ export default function NotTodoCreatePage() {
placeHolder="절제할 나를 응원할 메시지를 입력해주세요."
rows={1}
maxLength={100}
readOnly={isComplete}
/>
</div>
<div className="w-full mb-24"></div>
</div>

{/* next button */}
<div className="fixed bottom-0 left-0 w-full h-[88px] border-t border-t-gray bg-white">
{renderButton(isEditPage)}
</div>
{!isComplete && (
<div className="fixed bottom-0 left-0 w-full h-[88px] border-t border-t-gray bg-white">
{renderButton(isEditPage)}
</div>
)}
</div>
);
}
Loading

0 comments on commit 311594d

Please sign in to comment.