Skip to content

Commit

Permalink
feat: 새폴더만들기 모달 작성
Browse files Browse the repository at this point in the history
  • Loading branch information
miro-ring committed Feb 12, 2024
1 parent 73ba176 commit 35bd7b1
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 2 deletions.
3 changes: 3 additions & 0 deletions src/components/Modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useModalStore } from '@stores/modal';

import DeleteArticle from './modals/DeleteArticle';
import Login from './modals/Login';
import MakeFolder from './modals/MakeFolder';

const Modal = () => {
const { type } = useModalStore();
Expand All @@ -10,6 +11,8 @@ const Modal = () => {

if (type === 'login') return <Login />;

if (type === 'makeFolder') return <MakeFolder />;

return null;
};

Expand Down
2 changes: 1 addition & 1 deletion src/components/Modal/modals/DeleteArticle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const DeleteArticle = () => {
<p className={styles.body}>
{'삭제한 글은 복구할 수 없어요!\n삭제하시겠어요'}
</p>
<div>
<div className={styles.buttonWrapper}>
<button
type="button"
className={styles.button}
Expand Down
98 changes: 98 additions & 0 deletions src/components/Modal/modals/MakeFolder.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { type ChangeEvent, useState } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import { assignInlineVars } from '@vanilla-extract/dynamic';
import { AxiosError } from 'axios';
import clsx from 'clsx';

import Button from '@components/Button';
import Icon from '@components/Icon';
import ModalContainer from '@components/Modal/components/ModalContainer';
import * as styles from '@components/Modal/style.css';
import usePostMemoFolders from '@queries/usePostMemoFolders';
import { useModalStore } from '@stores/modal';
import { COLORS } from '@styles/tokens';

const MakeFolder = () => {
const queryClient = useQueryClient();

const { closeModal } = useModalStore();
const [value, setValue] = useState('');
const [errorMessage, setErrorMessage] = useState('');

const { mutateAsync } = usePostMemoFolders();

const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
setErrorMessage('');
setValue(e.target.value);
};

const handle만들기Click = async () => {
if (value.length > 10) return setErrorMessage('10자 내로 입력해주세요!');

try {
await mutateAsync(value);
await queryClient.invalidateQueries({
queryKey: ['memo-folders'],
});
closeModal();
} catch (e) {
if (!(e instanceof AxiosError) || !e.response) throw e;
if (e.response.data.errorCode === 'MF01')
return setErrorMessage('이미 사용 중인 폴더 이름이에요!');
throw e;
}
};

return (
<ModalContainer>
<strong className={styles.makeFolderTitle}>새 폴더 만들기</strong>
<label htmlFor="makeFolder" className={styles.makeFolderDescription}>
폴더 이름
</label>
<div className={styles.makeFolderInputWrapper}>
<input
id="makeFolder"
className={clsx(
styles.makeFolderInput,
errorMessage && styles.errorInput,
)}
placeholder="새 폴더 이름을 입력해주세요 (ex. 축하)"
onChange={handleInputChange}
/>
</div>
{errorMessage && (
<span className={styles.errorMessage}>
<div className={styles.errorIcon}>
<Icon width={20} height={20} icon="error" />
</div>
{errorMessage}
</span>
)}
<div className={styles.makeFolderButtonWrapper}>
<Button
className={styles.button}
style={assignInlineVars({
[styles.buttonColor]: COLORS['Grey/600'],
[styles.buttonBackgroundColor]: COLORS['Grey/150'],
})}
onClick={closeModal}
>
취소
</Button>
<Button
className={clsx(styles.button, !value && styles.buttonDisabled)}
disabled={!value}
style={assignInlineVars({
[styles.buttonColor]: COLORS['Grey/White'],
[styles.buttonBackgroundColor]: COLORS['Blue/Default'],
})}
onClick={handle만들기Click}
>
만들기
</Button>
</div>
</ModalContainer>
);
};

export default MakeFolder;
62 changes: 61 additions & 1 deletion src/components/Modal/style.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ export const button = style([
backgroundColor: buttonBackgroundColor,
padding: '16px 40px',
borderRadius: '8px',
marginTop: '24px',
selectors: {
'& + &': {
marginLeft: '8px',
Expand All @@ -88,6 +87,14 @@ export const button = style([
},
]);

export const buttonWrapper = style({
marginTop: '24px',
});

export const buttonDisabled = style({
opacity: '0.5',
});

export const helloImage = style({
textAlign: 'center',
});
Expand Down Expand Up @@ -203,3 +210,56 @@ export const agreeDescription = style([
export const agreeLink = style({
textDecorationLine: 'underline',
});

export const makeFolderTitle = style([
title,
{
marginBottom: '28px',
},
]);

export const makeFolderDescription = style([
sprinkles({
typography: '15/Body/Regular',
}),
{
color: COLORS['Grey/700'],
},
]);

export const makeFolderInputWrapper = style({
margin: '12px 0',
});

export const makeFolderInput = style({
padding: '12px 16px',
color: COLORS['Grey/600'],
backgroundColor: '#f0f0f0',
borderRadius: '8px',
height: '48px',
width: '100%',
});

export const errorInput = style({
border: `1.5px solid ${COLORS['Red']}`,
});
export const makeFolderButtonWrapper = style({
paddingTop: '16px',
});

export const errorMessage = style([
sprinkles({
typography: '13/Title/Semibold',
}),
{
display: 'block',
marginBottom: '8px',
color: COLORS['Red'],
},
]);

export const errorIcon = style({
display: 'inline-block',
verticalAlign: '-5px',
marginRight: '6px',
});

0 comments on commit 35bd7b1

Please sign in to comment.