inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[인프런 워밍업 클럽 3기 풀스택 ] 2주차 발자국

hee j
0

목차



Dropbox Clone Project

1. Drag & Drop 할 영역 설정

npm i --save react-dropzone
export default function FileDragDropZone() {
  const uploadImageMutation = useMutation({
    mutationFn: uploadFile,
    onSuccess: () => {
      queryClient.invalidateQueries({
        queryKey: ["images"], // images로 시작하는 것들 전부 리셋
      });
    },
  });

  const onDrop = useCallback(async (acceptedFiles) => {
   // 10개 이하의 파일만 업로드함
    if (acceptedFiles.length > 0 && acceptedFiles.length <= 10) {
      const formData = new FormData();

      acceptedFiles.forEach((file) => {
        formData.append(file.name, file);
      });

      await uploadImageMutation.mutate(formData);
    }
  }, []);
  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    onDrop,
    multiple: true, 
  });

  return (
    <div
      {...getRootProps()}
      className="w-full border-4 border-dotted border-blue-700 flex flex-col items-center justify-center py-20 cursor-pointer"
    >
      <input {...getInputProps()} />
      {uploadImageMutation.isPending ? (
        <Spinner />
      ) : isDragActive ? (
        <p>파일을 놓아주세요.</p>
      ) : (
        <p>파일을 여기에 끌어다 놓거나 클릭하여 업로드 하세요.</p>
      )}
    </div>
  );
}

 

2. supabase의 Storage에 첨부파일 업로드

NEXT_PUBLIC_STORAGE_BUCKET=minibox
export async function uploadFile(formData: FormData) {
  const files = Array.from(formData.entries()).map(
    ([name, file]) => file as File
  );
// all(): 여러 파일을 한 번에 업로드 진행하기 위해 사용
  const results = await Promise.all(
    files.map((file) => {
      supabase.storage
        .from(process.env.NEXT_PUBLIC_STORAGE_BUCKET)
        .upload(file.name, file, { upsert: true });
    })
  );
  return results;

 

3. 첨부파일 검색, 삭제

export async function searchFiles(search: string = "") {
  const supabase = await createServerSupabaseClient();
  const { data, error } = await supabase.storage
    .from(process.env.NEXT_PUBLIC_STORAGE_BUCKET)
    .list(null, { search }); // path, options, parameters
  handleError(error);
  return data;
}

export async function deleteFile(fileName: string) {
  const supabase = await createServerSupabaseClient();
  const { data, error } = await supabase.storage
    .from(process.env.NEXT_PUBLIC_STORAGE_BUCKET)
    .remove([fileName]);

  handleError(error);

  return data;
}

 

2주차 미션

[미션 완성 이미지]

image

[파일의 마지막 수정(업로드) 시간을 표시하기]

const formData = (dateString: string) => {
    return format(new Date(dateString), "yyyy-MM-dd HH:mm:ss");
  };

return (
    ...
    {/* FileName */}
    <div>{image.name}</div>
    <div>수정된 시간: {formData(image.updated_at)}</div>
    ...
)

 

[파일명을 UUID로 변경하여 업로드하기]

- 한글명 파일이 업로드 되지 않아 uuid로 파일 명을 변경하여 업로드 해보았음

- 업로드는 잘 되나 같은 파일을 업로드 하여도 파일 명이 변경되어 업로드 되기 때문에 새로 업로드 되어 업로드 시간이 변경되지 않아 적용하지는 않음

npm install uuid
const results = await Promise.all(
    files.map((file) => {
      const ext = file.name.split(".").pop(); // 확장자 추출
      const fileName = `${uuidv4()}.${ext}`; // UUID 기반 파일명 생성
      supabase.storage
        .from(process.env.NEXT_PUBLIC_STORAGE_BUCKET)
        .upload(fileName, file, { upsert: true });
    })
  );

풀스택 풀스택 next.js react supabase 워밍업 발자국

답변 0