-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* refactor: 모달 내부 컴포넌트 분리 * feat: 새로운 browseFileModal 생성 * feat: selectedFilesModal 생성 * feat: 새로운 퍼널 생성 * feat: 모달에서 업로드한 파일 전달 로직 구현 * docs: 퍼널 구조 hook으로 재배치 * chore: import 문 수정
- Loading branch information
Showing
19 changed files
with
456 additions
and
153 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
5 changes: 1 addition & 4 deletions
5
...rowseFile/FileHeader/BrowseFileHeader.tsx → ...ent/BrowseFileHeader/BrowseFileHeader.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
101 changes: 101 additions & 0 deletions
101
apps/client/src/shared/component/BrowseFileModal/BrowseFileModal.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import { IcSearch } from '@tiki/icon'; | ||
import { Button, Flex, Input } from '@tiki/ui'; | ||
import { useDebounce } from '@tiki/utils'; | ||
|
||
import { useState } from 'react'; | ||
|
||
import { components } from '@/shared/__generated__/schema'; | ||
import BrowseFileHeader from '@/shared/component/BrowseFileHeader/BrowseFileHeader'; | ||
import BrowseFileItem from '@/shared/component/BrowseFileItem/BrowseFileItem'; | ||
import { Modal } from '@/shared/component/Modal'; | ||
import { scrollContainerStyle } from '@/shared/component/TimeBlockModal/component/UploadModal/UploadModal.style'; | ||
import { useFunnel } from '@/shared/hook/common/useFunnel'; | ||
import { useCloseModal, useModalIsOpen } from '@/shared/store/modal'; | ||
|
||
type DocumentDetail = components['schemas']['DocumentInfoGetResponse']; | ||
|
||
interface BrowseFileProps { | ||
files: DocumentDetail[]; | ||
selectedFiles: DocumentDetail[]; | ||
onShowBlockAdd: () => void; | ||
onConfirmFile: (selectedFiles: DocumentDetail[]) => void; | ||
} | ||
|
||
const BrowseFileModal = ({ files, onShowBlockAdd, onConfirmFile }: BrowseFileProps) => { | ||
const [selectedFiles, setSelectedFiles] = useState<DocumentDetail[]>([]); | ||
const [searchFile, setSearchFile] = useState(''); | ||
|
||
const isOpen = useModalIsOpen(); | ||
const closeModal = useCloseModal(); | ||
const { nextStep } = useFunnel(); | ||
|
||
const isButtonActive = selectedFiles.length !== 0; | ||
const filterKeyword = useDebounce(searchFile, 500); | ||
|
||
const filteredFiles = files.filter((file) => file.name.normalize('NFC').includes(filterKeyword.normalize('NFC'))); | ||
|
||
const handleFileSelect = (file: DocumentDetail) => { | ||
setSelectedFiles((prevSelectedFiles) => { | ||
const isSelected = prevSelectedFiles.some((selectedFile) => selectedFile.documentId === file.documentId); | ||
|
||
const updatedFiles = isSelected | ||
? prevSelectedFiles.filter((selectedFile) => selectedFile.documentId !== file.documentId) | ||
: [...prevSelectedFiles, file]; | ||
|
||
onConfirmFile(updatedFiles); | ||
return updatedFiles; | ||
}); | ||
}; | ||
|
||
const handleNext = () => { | ||
nextStep(); | ||
}; | ||
|
||
return ( | ||
<Modal size="large" isOpen={isOpen} onClose={closeModal}> | ||
<Modal.Header /> | ||
<Modal.Body> | ||
<Flex css={{ flexDirection: 'column', gap: '2rem', width: '100%', paddingTop: '2rem' }}> | ||
<Flex css={{ flexDirection: 'row', alignItems: 'center', gap: '0.4rem', width: '100%' }}> | ||
<Input | ||
placeholder="문서를 검색해보세요" | ||
value={searchFile} | ||
LeftIcon={<IcSearch width={16} height={16} />} | ||
onChange={(e) => setSearchFile(e.target.value)} | ||
/> | ||
<Button variant="secondary" size="large" onClick={onShowBlockAdd}> | ||
파일 업로드 | ||
</Button> | ||
</Flex> | ||
|
||
<div css={scrollContainerStyle}> | ||
<BrowseFileHeader /> | ||
<ul css={{ marginTop: '4.8rem' }}> | ||
{filteredFiles.map((file) => ( | ||
<BrowseFileItem | ||
key={file.documentId} | ||
documentId={file.documentId} | ||
name={file.name} | ||
capacity={file.capacity} | ||
url={file.url} | ||
createdTime={file.createdTime} | ||
isSelected={selectedFiles.some((selectedFile) => selectedFile.documentId === file.documentId)} | ||
onSelect={() => handleFileSelect(file)} | ||
/> | ||
))} | ||
</ul> | ||
</div> | ||
</Flex> | ||
</Modal.Body> | ||
<Modal.Footer | ||
step={1} | ||
contentType="timeblock-file" | ||
buttonClick={handleNext} | ||
closeModal={closeModal} | ||
isButtonActive={isButtonActive} | ||
/> | ||
</Modal> | ||
); | ||
}; | ||
|
||
export default BrowseFileModal; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
...lient/src/shared/component/NewFileImportModal/FileUploadContainer/FileUploadContainer.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { IcFileUpload } from '@tiki/icon'; | ||
import { Button, Flex, Text } from '@tiki/ui'; | ||
|
||
import React, { Dispatch, SetStateAction } from 'react'; | ||
|
||
import { Files } from '@/shared/api/time-blocks/team/time-block/type'; | ||
import { FileWithDocumentId } from '@/shared/component/NewFileImportModal/NewFileImportModal'; | ||
import { boxStyle, uploadBoxStyle } from '@/shared/component/NewFileImportModal/NewFileImportModal.style'; | ||
import useFile from '@/shared/component/TimeBlockModal/hook/common/useFile'; | ||
|
||
interface FileUploadContainerProps { | ||
size: 'medium' | 'large'; | ||
files: FileWithDocumentId[]; | ||
setFiles: Dispatch<SetStateAction<FileWithDocumentId[]>>; | ||
setFileUrls: React.Dispatch<React.SetStateAction<Files>>; | ||
setUploadStatus: React.Dispatch<React.SetStateAction<{ [key: string]: boolean }>>; | ||
} | ||
|
||
const FileUploadContainer = ({ size, files, setFiles, setFileUrls, setUploadStatus }: FileUploadContainerProps) => { | ||
const { fileInputRef, handleFileChange, handleDragOver, handleDrop } = useFile({ | ||
files, | ||
onFilesChange: (newFiles) => { | ||
setFiles((prevFiles) => { | ||
const uniqueFiles = newFiles.filter( | ||
(newFile) => !prevFiles.some((file) => file.name === newFile.name && file.size === newFile.size) | ||
); | ||
|
||
return [...prevFiles, ...uniqueFiles]; | ||
}); | ||
}, | ||
setFileUrls, | ||
setUploadStatus, | ||
}); | ||
|
||
return ( | ||
<Flex css={[boxStyle, uploadBoxStyle(size)]} onDragOver={handleDragOver} onDrop={(event) => handleDrop(event)}> | ||
<Flex tag="form" styles={{ direction: 'column', align: 'center', justify: 'center' }}> | ||
<input type="file" multiple style={{ display: 'none' }} ref={fileInputRef} onChange={handleFileChange} /> | ||
<IcFileUpload width={32} height={32} css={{ marginBottom: '1.2rem' }} /> | ||
<Flex styles={{ direction: 'column', gap: '0.8rem', align: 'center', justify: 'center' }}> | ||
<Text tag="body6" css={{ marginBottom: '0.8rem' }}> | ||
업로드할 파일을 끌어다 놓으세요. | ||
</Text> | ||
<Text tag="body8" css={{ whiteSpace: 'nowrap' }}> | ||
JPEG, PNG, PDF, Word 형식의 파일을 업로드할 수 있습니다. | ||
</Text> | ||
<Text tag="body8" css={{ marginBottom: '2rem' }}> | ||
최대 파일 크기는 50MB입니다. | ||
</Text> | ||
</Flex> | ||
<Button variant="outline" css={{ width: '16rem' }} onClick={() => fileInputRef.current?.click()}> | ||
파일 브라우저 | ||
</Button> | ||
</Flex> | ||
</Flex> | ||
); | ||
}; | ||
|
||
export default FileUploadContainer; |
Oops, something went wrong.