Merge branch 'fe/refactor/image-upload' into 'fe/develop'
Refactor: 이미지 업로드 컴포넌트 리팩토링 - S11P21S002-243 See merge request s11-s-project/S11P21S002!239
This commit is contained in:
commit
c0e25cc2f1
@ -31,7 +31,13 @@ export async function changeImageStatus(
|
|||||||
.then(({ data }) => data);
|
.then(({ data }) => data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function uploadImageFile(memberId: number, projectId: number, folderId: number, files: File[]) {
|
export async function uploadImageFile(
|
||||||
|
memberId: number,
|
||||||
|
projectId: number,
|
||||||
|
folderId: number,
|
||||||
|
files: File[],
|
||||||
|
processCallback: (progress: number) => void
|
||||||
|
) {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
files.forEach((file) => {
|
files.forEach((file) => {
|
||||||
formData.append('imageList', file);
|
formData.append('imageList', file);
|
||||||
@ -40,30 +46,60 @@ export async function uploadImageFile(memberId: number, projectId: number, folde
|
|||||||
return api
|
return api
|
||||||
.post(`/projects/${projectId}/folders/${folderId}/images/file`, formData, {
|
.post(`/projects/${projectId}/folders/${folderId}/images/file`, formData, {
|
||||||
params: { memberId },
|
params: { memberId },
|
||||||
|
onUploadProgress: (progressEvent) => {
|
||||||
|
if (progressEvent.total) {
|
||||||
|
const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total);
|
||||||
|
processCallback(progress);
|
||||||
|
}
|
||||||
|
},
|
||||||
})
|
})
|
||||||
.then(({ data }) => data);
|
.then(({ data }) => data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function uploadImageFolder(memberId: number, projectId: number, files: File[]) {
|
export async function uploadImageFolder(
|
||||||
|
memberId: number,
|
||||||
|
projectId: number,
|
||||||
|
folderId: number,
|
||||||
|
files: File[],
|
||||||
|
processCallback: (progress: number) => void
|
||||||
|
) {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
files.forEach((file) => {
|
files.forEach((file) => {
|
||||||
formData.append('imageList', file);
|
formData.append('imageList', file);
|
||||||
});
|
});
|
||||||
|
|
||||||
return api
|
return api
|
||||||
.post(`/projects/${projectId}/folders/${0}/images/file`, formData, {
|
.post(`/projects/${projectId}/folders/${folderId}/images/file`, formData, {
|
||||||
params: { memberId },
|
params: { memberId },
|
||||||
|
onUploadProgress: (progressEvent) => {
|
||||||
|
if (progressEvent.total) {
|
||||||
|
const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total);
|
||||||
|
processCallback(progress);
|
||||||
|
}
|
||||||
|
},
|
||||||
})
|
})
|
||||||
.then(({ data }) => data);
|
.then(({ data }) => data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function uploadImageZip(memberId: number, projectId: number, file: File) {
|
export async function uploadImageZip(
|
||||||
|
memberId: number,
|
||||||
|
projectId: number,
|
||||||
|
folderId: number,
|
||||||
|
file: File,
|
||||||
|
processCallback: (progress: number) => void
|
||||||
|
) {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('folderZip', file);
|
formData.append('folderZip', file);
|
||||||
|
|
||||||
return api
|
return api
|
||||||
.post(`/projects/${projectId}/folders/${0}/images/zip`, formData, {
|
.post(`/projects/${projectId}/folders/${folderId}/images/zip`, formData, {
|
||||||
params: { memberId },
|
params: { memberId },
|
||||||
|
onUploadProgress: (progressEvent) => {
|
||||||
|
if (progressEvent.total) {
|
||||||
|
const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total);
|
||||||
|
processCallback(progress);
|
||||||
|
}
|
||||||
|
},
|
||||||
})
|
})
|
||||||
.then(({ data }) => data);
|
.then(({ data }) => data);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { Button } from '../ui/button';
|
import { Button } from '../ui/button';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import useAuthStore from '@/stores/useAuthStore';
|
import useAuthStore from '@/stores/useAuthStore';
|
||||||
@ -7,10 +7,14 @@ import useUploadImageFileQuery from '@/queries/projects/useUploadImageFileQuery'
|
|||||||
|
|
||||||
export default function ImageUploadFileForm({
|
export default function ImageUploadFileForm({
|
||||||
onClose,
|
onClose,
|
||||||
|
onRefetch,
|
||||||
|
onFileCount,
|
||||||
projectId,
|
projectId,
|
||||||
folderId,
|
folderId,
|
||||||
}: {
|
}: {
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
onRefetch: () => void;
|
||||||
|
onFileCount: (fileCount: number) => void;
|
||||||
projectId: number;
|
projectId: number;
|
||||||
folderId: number;
|
folderId: number;
|
||||||
}) {
|
}) {
|
||||||
@ -22,6 +26,7 @@ export default function ImageUploadFileForm({
|
|||||||
const [isUploading, setIsUploading] = useState<boolean>(false);
|
const [isUploading, setIsUploading] = useState<boolean>(false);
|
||||||
const [isUploaded, setIsUploaded] = useState<boolean>(false);
|
const [isUploaded, setIsUploaded] = useState<boolean>(false);
|
||||||
const [isFailed, setIsFailed] = useState<boolean>(false);
|
const [isFailed, setIsFailed] = useState<boolean>(false);
|
||||||
|
const [progress, setProgress] = useState<number>(0);
|
||||||
|
|
||||||
const uploadImageFile = useUploadImageFileQuery();
|
const uploadImageFile = useUploadImageFileQuery();
|
||||||
|
|
||||||
@ -71,9 +76,13 @@ export default function ImageUploadFileForm({
|
|||||||
projectId,
|
projectId,
|
||||||
folderId,
|
folderId,
|
||||||
files,
|
files,
|
||||||
|
progressCallback: (progress: number) => {
|
||||||
|
setProgress(progress);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
|
onRefetch();
|
||||||
setIsUploaded(true);
|
setIsUploaded(true);
|
||||||
},
|
},
|
||||||
onError: () => {
|
onError: () => {
|
||||||
@ -83,6 +92,10 @@ export default function ImageUploadFileForm({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
onFileCount(files.length);
|
||||||
|
}, [files, onFileCount]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-5">
|
<div className="flex flex-col gap-5">
|
||||||
{!isUploading && (
|
{!isUploading && (
|
||||||
@ -115,11 +128,11 @@ export default function ImageUploadFileForm({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{files.length > 0 && (
|
{files.length > 0 && (
|
||||||
<ul className="m-0 max-h-[200px] list-none overflow-y-auto p-0">
|
<ul className="m-0 max-h-[260px] list-none overflow-y-auto p-0">
|
||||||
{files.map((file, index) => (
|
{files.map((file, index) => (
|
||||||
<li
|
<li
|
||||||
key={index}
|
key={index}
|
||||||
className={cn('flex items-center justify-between p-1')}
|
className="flex items-center justify-between p-1"
|
||||||
>
|
>
|
||||||
<span className="truncate">{file.webkitRelativePath || file.name}</span>
|
<span className="truncate">{file.webkitRelativePath || file.name}</span>
|
||||||
{isUploading ? (
|
{isUploading ? (
|
||||||
@ -127,19 +140,19 @@ export default function ImageUploadFileForm({
|
|||||||
{isUploaded ? (
|
{isUploaded ? (
|
||||||
<CircleCheckBig
|
<CircleCheckBig
|
||||||
className="stroke-green-500"
|
className="stroke-green-500"
|
||||||
size={20}
|
size={16}
|
||||||
strokeWidth="2"
|
strokeWidth="2"
|
||||||
/>
|
/>
|
||||||
) : isFailed ? (
|
) : isFailed ? (
|
||||||
<CircleX
|
<CircleX
|
||||||
className="stroke-red-500"
|
className="stroke-red-500"
|
||||||
size={20}
|
size={16}
|
||||||
strokeWidth="2"
|
strokeWidth="2"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<CircleDashed
|
<CircleDashed
|
||||||
className="stroke-gray-500"
|
className="stroke-gray-500"
|
||||||
size={20}
|
size={16}
|
||||||
strokeWidth="2"
|
strokeWidth="2"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -171,7 +184,7 @@ export default function ImageUploadFileForm({
|
|||||||
}
|
}
|
||||||
disabled={!isUploaded && !isFailed}
|
disabled={!isUploaded && !isFailed}
|
||||||
>
|
>
|
||||||
{isFailed ? '업로드 실패 (닫기)' : isUploaded ? '업로드 완료 (닫기)' : '업로드 중...'}
|
{isFailed ? '업로드 실패 (닫기)' : isUploaded ? '업로드 완료 (닫기)' : `업로드 중... ${progress}%`}
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
|
@ -4,10 +4,14 @@ import { Plus } from 'lucide-react';
|
|||||||
import ImageUploadFileForm from './ImageUploadFileForm';
|
import ImageUploadFileForm from './ImageUploadFileForm';
|
||||||
|
|
||||||
export default function ImageUploadFileModal({ projectId, folderId }: { projectId: number; folderId: number }) {
|
export default function ImageUploadFileModal({ projectId, folderId }: { projectId: number; folderId: number }) {
|
||||||
const [isOpen, setIsOpen] = React.useState(false);
|
const [isOpen, setIsOpen] = React.useState<boolean>(false);
|
||||||
|
const [fileCount, setFileCount] = React.useState<number>(0);
|
||||||
|
|
||||||
const handleOpen = () => setIsOpen(true);
|
const handleOpen = () => setIsOpen(true);
|
||||||
const handleClose = () => setIsOpen(false);
|
const handleClose = () => setIsOpen(false);
|
||||||
|
const handleFileCount = (fileCount: number) => {
|
||||||
|
setFileCount(fileCount);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
@ -23,9 +27,10 @@ export default function ImageUploadFileModal({ projectId, folderId }: { projectI
|
|||||||
</button>
|
</button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className="max-w-2xl">
|
<DialogContent className="max-w-2xl">
|
||||||
<DialogHeader title="파일 업로드" />
|
<DialogHeader title={fileCount > 0 ? `파일 업로드 (${fileCount})` : '파일 업로드'} />
|
||||||
<ImageUploadFileForm
|
<ImageUploadFileForm
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
|
onFileCount={handleFileCount}
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
folderId={folderId}
|
folderId={folderId}
|
||||||
/>
|
/>
|
||||||
|
@ -5,7 +5,17 @@ import useAuthStore from '@/stores/useAuthStore';
|
|||||||
import { CircleCheckBig, CircleDashed, CircleX, X } from 'lucide-react';
|
import { CircleCheckBig, CircleDashed, CircleX, X } from 'lucide-react';
|
||||||
import useUploadImageFolderQuery from '@/queries/projects/useUploadImageFolderQuery';
|
import useUploadImageFolderQuery from '@/queries/projects/useUploadImageFolderQuery';
|
||||||
|
|
||||||
export default function ImageUploadFolderForm({ onClose, projectId }: { onClose: () => void; projectId: number }) {
|
export default function ImageUploadFolderForm({
|
||||||
|
onClose,
|
||||||
|
onRefetch,
|
||||||
|
projectId,
|
||||||
|
folderId,
|
||||||
|
}: {
|
||||||
|
onClose: () => void;
|
||||||
|
onRefetch: () => void;
|
||||||
|
projectId: number;
|
||||||
|
folderId: number;
|
||||||
|
}) {
|
||||||
const profile = useAuthStore((state) => state.profile);
|
const profile = useAuthStore((state) => state.profile);
|
||||||
const memberId = profile?.id || 0;
|
const memberId = profile?.id || 0;
|
||||||
|
|
||||||
@ -14,6 +24,7 @@ export default function ImageUploadFolderForm({ onClose, projectId }: { onClose:
|
|||||||
const [isUploading, setIsUploading] = useState<boolean>(false);
|
const [isUploading, setIsUploading] = useState<boolean>(false);
|
||||||
const [isUploaded, setIsUploaded] = useState<boolean>(false);
|
const [isUploaded, setIsUploaded] = useState<boolean>(false);
|
||||||
const [isFailed, setIsFailed] = useState<boolean>(false);
|
const [isFailed, setIsFailed] = useState<boolean>(false);
|
||||||
|
const [progress, setProgress] = useState<number>(0);
|
||||||
|
|
||||||
const uploadImageFolder = useUploadImageFolderQuery();
|
const uploadImageFolder = useUploadImageFolderQuery();
|
||||||
|
|
||||||
@ -56,10 +67,15 @@ export default function ImageUploadFolderForm({ onClose, projectId }: { onClose:
|
|||||||
{
|
{
|
||||||
memberId,
|
memberId,
|
||||||
projectId,
|
projectId,
|
||||||
|
folderId,
|
||||||
files,
|
files,
|
||||||
|
progressCallback: (progress: number) => {
|
||||||
|
setProgress(progress);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
|
onRefetch;
|
||||||
setIsUploaded(true);
|
setIsUploaded(true);
|
||||||
},
|
},
|
||||||
onError: () => {
|
onError: () => {
|
||||||
@ -100,11 +116,11 @@ export default function ImageUploadFolderForm({ onClose, projectId }: { onClose:
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{files.length > 0 && (
|
{files.length > 0 && (
|
||||||
<ul className="m-0 max-h-[200px] list-none overflow-y-auto p-0">
|
<ul className="m-0 max-h-[260px] list-none overflow-y-auto p-0">
|
||||||
{files.map((file, index) => (
|
{files.map((file, index) => (
|
||||||
<li
|
<li
|
||||||
key={index}
|
key={index}
|
||||||
className={cn('flex items-center justify-between p-1')}
|
className="flex items-center justify-between p-1"
|
||||||
>
|
>
|
||||||
<span className="truncate">{file.webkitRelativePath || file.name}</span>
|
<span className="truncate">{file.webkitRelativePath || file.name}</span>
|
||||||
{isUploading ? (
|
{isUploading ? (
|
||||||
@ -112,19 +128,19 @@ export default function ImageUploadFolderForm({ onClose, projectId }: { onClose:
|
|||||||
{isUploaded ? (
|
{isUploaded ? (
|
||||||
<CircleCheckBig
|
<CircleCheckBig
|
||||||
className="stroke-green-500"
|
className="stroke-green-500"
|
||||||
size={20}
|
size={16}
|
||||||
strokeWidth="2"
|
strokeWidth="2"
|
||||||
/>
|
/>
|
||||||
) : isFailed ? (
|
) : isFailed ? (
|
||||||
<CircleX
|
<CircleX
|
||||||
className="stroke-red-500"
|
className="stroke-red-500"
|
||||||
size={20}
|
size={16}
|
||||||
strokeWidth="2"
|
strokeWidth="2"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<CircleDashed
|
<CircleDashed
|
||||||
className="stroke-gray-500"
|
className="stroke-gray-500"
|
||||||
size={20}
|
size={16}
|
||||||
strokeWidth="2"
|
strokeWidth="2"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -156,7 +172,7 @@ export default function ImageUploadFolderForm({ onClose, projectId }: { onClose:
|
|||||||
}
|
}
|
||||||
disabled={!isUploaded && !isFailed}
|
disabled={!isUploaded && !isFailed}
|
||||||
>
|
>
|
||||||
{isFailed ? '업로드 실패 (닫기)' : isUploaded ? '업로드 완료 (닫기)' : '업로드 중...'}
|
{isFailed ? '업로드 실패 (닫기)' : isUploaded ? '업로드 완료 (닫기)' : `업로드 중... ${progress}%`}
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
|
@ -3,7 +3,7 @@ import { Dialog, DialogContent, DialogHeader, DialogTrigger } from '../ui/dialog
|
|||||||
import { Plus } from 'lucide-react';
|
import { Plus } from 'lucide-react';
|
||||||
import ImageUploadFolderForm from './ImageUploadFolderForm';
|
import ImageUploadFolderForm from './ImageUploadFolderForm';
|
||||||
|
|
||||||
export default function ImageUploadFolderModal({ projectId }: { projectId: number }) {
|
export default function ImageUploadFolderModal({ projectId, folderId }: { projectId: number; folderId: number }) {
|
||||||
const [isOpen, setIsOpen] = React.useState(false);
|
const [isOpen, setIsOpen] = React.useState(false);
|
||||||
|
|
||||||
const handleOpen = () => setIsOpen(true);
|
const handleOpen = () => setIsOpen(true);
|
||||||
@ -27,6 +27,7 @@ export default function ImageUploadFolderModal({ projectId }: { projectId: numbe
|
|||||||
<ImageUploadFolderForm
|
<ImageUploadFolderForm
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
|
folderId={folderId}
|
||||||
/>
|
/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
@ -5,7 +5,17 @@ import useAuthStore from '@/stores/useAuthStore';
|
|||||||
import { CircleCheckBig, CircleDashed, CircleX, X } from 'lucide-react';
|
import { CircleCheckBig, CircleDashed, CircleX, X } from 'lucide-react';
|
||||||
import useUploadImageZipQuery from '@/queries/projects/useUploadImageZipQuery';
|
import useUploadImageZipQuery from '@/queries/projects/useUploadImageZipQuery';
|
||||||
|
|
||||||
export default function ImageUploadZipForm({ onClose, projectId }: { onClose: () => void; projectId: number }) {
|
export default function ImageUploadZipForm({
|
||||||
|
onClose,
|
||||||
|
onRefetch,
|
||||||
|
projectId,
|
||||||
|
folderId,
|
||||||
|
}: {
|
||||||
|
onClose: () => void;
|
||||||
|
onRefetch: () => void;
|
||||||
|
projectId: number;
|
||||||
|
folderId: number;
|
||||||
|
}) {
|
||||||
const profile = useAuthStore((state) => state.profile);
|
const profile = useAuthStore((state) => state.profile);
|
||||||
const memberId = profile?.id || 0;
|
const memberId = profile?.id || 0;
|
||||||
|
|
||||||
@ -14,6 +24,7 @@ export default function ImageUploadZipForm({ onClose, projectId }: { onClose: ()
|
|||||||
const [isUploading, setIsUploading] = useState<boolean>(false);
|
const [isUploading, setIsUploading] = useState<boolean>(false);
|
||||||
const [isUploaded, setIsUploaded] = useState<boolean>(false);
|
const [isUploaded, setIsUploaded] = useState<boolean>(false);
|
||||||
const [isFailed, setIsFailed] = useState<boolean>(false);
|
const [isFailed, setIsFailed] = useState<boolean>(false);
|
||||||
|
const [progress, setProgress] = useState<number>(0);
|
||||||
|
|
||||||
const uploadImageZip = useUploadImageZipQuery();
|
const uploadImageZip = useUploadImageZipQuery();
|
||||||
|
|
||||||
@ -57,10 +68,15 @@ export default function ImageUploadZipForm({ onClose, projectId }: { onClose: ()
|
|||||||
{
|
{
|
||||||
memberId,
|
memberId,
|
||||||
projectId,
|
projectId,
|
||||||
|
folderId,
|
||||||
file,
|
file,
|
||||||
|
progressCallback: (progress: number) => {
|
||||||
|
setProgress(progress);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
|
onRefetch();
|
||||||
setIsUploaded(true);
|
setIsUploaded(true);
|
||||||
},
|
},
|
||||||
onError: () => {
|
onError: () => {
|
||||||
@ -110,19 +126,19 @@ export default function ImageUploadZipForm({ onClose, projectId }: { onClose: ()
|
|||||||
{isUploaded ? (
|
{isUploaded ? (
|
||||||
<CircleCheckBig
|
<CircleCheckBig
|
||||||
className="stroke-green-500"
|
className="stroke-green-500"
|
||||||
size={20}
|
size={16}
|
||||||
strokeWidth="2"
|
strokeWidth="2"
|
||||||
/>
|
/>
|
||||||
) : isFailed ? (
|
) : isFailed ? (
|
||||||
<CircleX
|
<CircleX
|
||||||
className="stroke-red-500"
|
className="stroke-red-500"
|
||||||
size={20}
|
size={16}
|
||||||
strokeWidth="2"
|
strokeWidth="2"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<CircleDashed
|
<CircleDashed
|
||||||
className="stroke-gray-500"
|
className="stroke-gray-500"
|
||||||
size={20}
|
size={16}
|
||||||
strokeWidth="2"
|
strokeWidth="2"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -152,7 +168,7 @@ export default function ImageUploadZipForm({ onClose, projectId }: { onClose: ()
|
|||||||
}
|
}
|
||||||
disabled={!isUploaded && !isFailed}
|
disabled={!isUploaded && !isFailed}
|
||||||
>
|
>
|
||||||
{isFailed ? '업로드 실패 (닫기)' : isUploaded ? '업로드 완료 (닫기)' : '업로드 중...'}
|
{isFailed ? '업로드 실패 (닫기)' : isUploaded ? '업로드 완료 (닫기)' : `업로드 중... ${progress}%`}
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
|
@ -3,7 +3,7 @@ import { Dialog, DialogContent, DialogHeader, DialogTrigger } from '../ui/dialog
|
|||||||
import { Plus } from 'lucide-react';
|
import { Plus } from 'lucide-react';
|
||||||
import ImageUploadZipForm from './ImageUploadZipForm';
|
import ImageUploadZipForm from './ImageUploadZipForm';
|
||||||
|
|
||||||
export default function ImageUploadZipModal({ projectId }: { projectId: number }) {
|
export default function ImageUploadZipModal({ projectId, folderId }: { projectId: number; folderId: number }) {
|
||||||
const [isOpen, setIsOpen] = React.useState(false);
|
const [isOpen, setIsOpen] = React.useState(false);
|
||||||
|
|
||||||
const handleOpen = () => setIsOpen(true);
|
const handleOpen = () => setIsOpen(true);
|
||||||
@ -27,6 +27,7 @@ export default function ImageUploadZipModal({ projectId }: { projectId: number }
|
|||||||
<ImageUploadZipForm
|
<ImageUploadZipForm
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
|
folderId={folderId}
|
||||||
/>
|
/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
@ -15,32 +15,40 @@ import ImageUploadZipForm from '../ImageUploadZipModal/ImageUploadZipForm';
|
|||||||
export default function WorkspaceDropdownMenu({
|
export default function WorkspaceDropdownMenu({
|
||||||
projectId,
|
projectId,
|
||||||
folderId,
|
folderId,
|
||||||
refetch,
|
onRefetch,
|
||||||
}: {
|
}: {
|
||||||
projectId: number;
|
projectId: number;
|
||||||
folderId: number;
|
folderId: number;
|
||||||
refetch: () => void;
|
onRefetch: () => void;
|
||||||
}) {
|
}) {
|
||||||
const [isOpenUploadFile, setIsOpenUploadFile] = React.useState(false);
|
const [isOpenUploadFile, setIsOpenUploadFile] = React.useState<boolean>(false);
|
||||||
const [isOpenUploadFolder, setIsOpenUploadFolder] = React.useState(false);
|
const [fileCount, setFileCount] = React.useState<number>(0);
|
||||||
const [isOpenUploadZip, setIsOpenUploadZip] = React.useState(false);
|
const [isOpenUploadFolder, setIsOpenUploadFolder] = React.useState<boolean>(false);
|
||||||
|
const [isOpenUploadZip, setIsOpenUploadZip] = React.useState<boolean>(false);
|
||||||
|
|
||||||
const handleOpenUploadFile = () => setIsOpenUploadFile(true);
|
const handleOpenUploadFile = () => setIsOpenUploadFile(true);
|
||||||
|
|
||||||
const handleCloseUploadFile = () => {
|
const handleCloseUploadFile = () => {
|
||||||
refetch();
|
|
||||||
setIsOpenUploadFile(false);
|
setIsOpenUploadFile(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOpenUploadFolder = () => setIsOpenUploadFolder(true);
|
const handleOpenUploadFolder = () => setIsOpenUploadFolder(true);
|
||||||
|
|
||||||
const handleCloseUploadFolder = () => {
|
const handleCloseUploadFolder = () => {
|
||||||
refetch();
|
|
||||||
setIsOpenUploadFolder(false);
|
setIsOpenUploadFolder(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOpenUploadZip = () => setIsOpenUploadZip(true);
|
const handleOpenUploadZip = () => setIsOpenUploadZip(true);
|
||||||
|
|
||||||
const handleCloseUploadZip = () => {
|
const handleCloseUploadZip = () => {
|
||||||
refetch();
|
|
||||||
setIsOpenUploadZip(false);
|
setIsOpenUploadZip(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleFileCount = (fileCount: number) => {
|
||||||
|
console.log(fileCount);
|
||||||
|
setFileCount(fileCount);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
@ -71,9 +79,11 @@ export default function WorkspaceDropdownMenu({
|
|||||||
>
|
>
|
||||||
<DialogTrigger asChild></DialogTrigger>
|
<DialogTrigger asChild></DialogTrigger>
|
||||||
<DialogContent className="max-w-2xl">
|
<DialogContent className="max-w-2xl">
|
||||||
<DialogHeader title="파일 업로드" />
|
<DialogHeader title={fileCount > 0 ? `파일 업로드 (${fileCount})` : '파일 업로드'} />
|
||||||
<ImageUploadFileForm
|
<ImageUploadFileForm
|
||||||
onClose={handleCloseUploadFile}
|
onClose={handleCloseUploadFile}
|
||||||
|
onRefetch={onRefetch}
|
||||||
|
onFileCount={handleFileCount}
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
folderId={folderId}
|
folderId={folderId}
|
||||||
/>
|
/>
|
||||||
@ -89,7 +99,9 @@ export default function WorkspaceDropdownMenu({
|
|||||||
<DialogHeader title="폴더 업로드 (임시)" />
|
<DialogHeader title="폴더 업로드 (임시)" />
|
||||||
<ImageUploadFolderForm
|
<ImageUploadFolderForm
|
||||||
onClose={handleCloseUploadFolder}
|
onClose={handleCloseUploadFolder}
|
||||||
|
onRefetch={onRefetch}
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
|
folderId={folderId}
|
||||||
/>
|
/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
@ -103,7 +115,9 @@ export default function WorkspaceDropdownMenu({
|
|||||||
<DialogHeader title="폴더 압축파일 업로드" />
|
<DialogHeader title="폴더 압축파일 업로드" />
|
||||||
<ImageUploadZipForm
|
<ImageUploadZipForm
|
||||||
onClose={handleCloseUploadZip}
|
onClose={handleCloseUploadZip}
|
||||||
|
onRefetch={onRefetch}
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
|
folderId={folderId}
|
||||||
/>
|
/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
@ -40,7 +40,7 @@ export default function ProjectStructure({ project }: { project: Project }) {
|
|||||||
<WorkspaceDropdownMenu
|
<WorkspaceDropdownMenu
|
||||||
projectId={project.id}
|
projectId={project.id}
|
||||||
folderId={0}
|
folderId={0}
|
||||||
refetch={refetch}
|
onRefetch={refetch}
|
||||||
/>
|
/>
|
||||||
</header>
|
</header>
|
||||||
{folderData.children.length === 0 && folderData.images.length === 0 ? (
|
{folderData.children.length === 0 && folderData.images.length === 0 ? (
|
||||||
|
@ -8,11 +8,13 @@ export default function useUploadImageFileQuery() {
|
|||||||
projectId,
|
projectId,
|
||||||
folderId,
|
folderId,
|
||||||
files,
|
files,
|
||||||
|
progressCallback,
|
||||||
}: {
|
}: {
|
||||||
memberId: number;
|
memberId: number;
|
||||||
projectId: number;
|
projectId: number;
|
||||||
folderId: number;
|
folderId: number;
|
||||||
files: File[];
|
files: File[];
|
||||||
}) => uploadImageFile(memberId, projectId, folderId, files),
|
progressCallback: (progress: number) => void;
|
||||||
|
}) => uploadImageFile(memberId, projectId, folderId, files, progressCallback),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,18 @@ import { useMutation } from '@tanstack/react-query';
|
|||||||
|
|
||||||
export default function useUploadImageFolderQuery() {
|
export default function useUploadImageFolderQuery() {
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: ({ memberId, projectId, files }: { memberId: number; projectId: number; files: File[] }) =>
|
mutationFn: ({
|
||||||
uploadImageFolder(memberId, projectId, files),
|
memberId,
|
||||||
|
projectId,
|
||||||
|
folderId,
|
||||||
|
files,
|
||||||
|
progressCallback,
|
||||||
|
}: {
|
||||||
|
memberId: number;
|
||||||
|
projectId: number;
|
||||||
|
folderId: number;
|
||||||
|
files: File[];
|
||||||
|
progressCallback: (progress: number) => void;
|
||||||
|
}) => uploadImageFolder(memberId, projectId, folderId, files, progressCallback),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,18 @@ import { useMutation } from '@tanstack/react-query';
|
|||||||
|
|
||||||
export default function useUploadImageZipQuery() {
|
export default function useUploadImageZipQuery() {
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: ({ memberId, projectId, file }: { memberId: number; projectId: number; file: File }) =>
|
mutationFn: ({
|
||||||
uploadImageZip(memberId, projectId, file),
|
memberId,
|
||||||
|
projectId,
|
||||||
|
folderId,
|
||||||
|
file,
|
||||||
|
progressCallback,
|
||||||
|
}: {
|
||||||
|
memberId: number;
|
||||||
|
projectId: number;
|
||||||
|
folderId: number;
|
||||||
|
file: File;
|
||||||
|
progressCallback: (progress: number) => void;
|
||||||
|
}) => uploadImageZip(memberId, projectId, folderId, file, progressCallback),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user