Skip to content

Commit

Permalink
react-dropzone による csv 取り込みを試してみる
Browse files Browse the repository at this point in the history
  • Loading branch information
kuramapommel committed Sep 1, 2024
1 parent 7933667 commit 122b5f4
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 1 deletion.
1 change: 1 addition & 0 deletions sample/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"react": "^18.3.1",
"react-admin": "^5.1.1",
"react-dom": "^18.3.1",
"react-dropzone": "^14.2.3",
"react-router-dom": "^6.24.1",
"zod": "^3.23.8",
"zustand": "^4.5.4"
Expand Down
27 changes: 27 additions & 0 deletions sample/src/components/organisms/products/dropzone.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Dropzone from '@/components/organisms/products/dropzone'
import type { Meta, StoryObj } from '@storybook/react'
import { useState } from 'react'

const meta: Meta<typeof Dropzone> = {
title: 'organisms/products/dropzone',
component: Dropzone,
parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
layout: 'centered',
},
tags: ['autodocs'],
}

export default meta

type Story = StoryObj<typeof Dropzone>

/**
* 一括登録ボタン
*/
export const Default: Story = {
render: () => {
const [file, setFile] = useState<File | null>(null)
return <Dropzone file={file} setFile={setFile} />
},
}
54 changes: 54 additions & 0 deletions sample/src/components/organisms/products/dropzone.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React, { useCallback } from 'react'
import { useDropzone } from 'react-dropzone'

type Props = {
file: File | null
setFile: (file: File) => void
}

const DropZone = React.memo(function DropZone({ file, setFile }: Props) {
const onDrop = useCallback(
async (acceptedFiles: File[]) => {
const importFile = acceptedFiles[0]
if (!importFile) return

setFile(importFile)
},
[setFile],
)
const {
getRootProps,
getInputProps,
isDragAccept,
isDragReject,
isDragActive,
} = useDropzone({
onDrop,
accept: {
'text/csv': ['.csv'],
},
maxFiles: 1,
})
const message = useCallback(() => {
if (file) return `${file.name} が読み込まれています`

if (isDragReject)
return 'ファイル形式が不正、もしくは複数のファイル取り込もうとしています。'

if (isDragActive && isDragAccept) return '読み込み可能な形式です'

return 'ファイルをここに D&D するか、クリックしてファイルを選択してください'
}, [file, isDragReject, isDragActive, isDragAccept])

return (
<div
{...getRootProps()}
className={`w-full min-h-56 border-dashed border-gray-800 border-2 flex items-center rounded-3xl justify-center ${file ? 'bg-green-200' : ''}`}
>
<input {...getInputProps()} />
<p className="text-center">{message()}</p>
</div>
)
})

export default DropZone
5 changes: 4 additions & 1 deletion sample/src/pages/product-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import ProductDeletionForm from '@/components/molecules/forms/products/product-d
import ProductEditingForm from '@/components/molecules/forms/products/product-editing-form'
import Modal from '@/components/molecules/modals/modal'
import BulkImportButton from '@/components/organisms/products/bulk-import-button'
import DropZone from '@/components/organisms/products/dropzone'
import TenantsTemplate from '@/components/templates/tenants-template'
import { useProducts } from '@/hooks/use-products'
import { getProductsAndRefresh } from '@/reducks/products/selectors'
import { Product } from '@/reducks/products/types'
import { css } from '@emotion/react'
import { useEffect, useState } from 'react'
import React, { useEffect, useState } from 'react'

const styles = {
button: css`
Expand Down Expand Up @@ -45,6 +46,7 @@ const ProductList: React.FC = () => {
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false)
const [currentProduct, setCurrentProduct] = useState<Product | null>(null)
const [productToDelete, setProductToDelete] = useState<Product | null>(null)
const [file, setFile] = useState<File | null>(null)

useEffect(() => {
refresh()
Expand All @@ -57,6 +59,7 @@ const ProductList: React.FC = () => {
新規作成
</button>
<BulkImportButton />
<DropZone file={file} setFile={setFile} />

{isDeleteDialogOpen && productToDelete && (
<div css={styles.overlay}>
Expand Down

0 comments on commit 122b5f4

Please sign in to comment.