Skip to content

Commit

Permalink
Merge pull request #96 from bssm-portfolio/develop
Browse files Browse the repository at this point in the history
v1.2.0
  • Loading branch information
J1min authored Mar 27, 2023
2 parents 7d9c62c + aa78bfc commit 7153ffb
Show file tree
Hide file tree
Showing 22 changed files with 346 additions and 123 deletions.
29 changes: 22 additions & 7 deletions apis/httpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,6 @@ export class HttpClient {
});
}

search(data: unknown, requestConfig?: AxiosRequestConfig) {
return this.api.post("/search", data, {
...HttpClient.clientConfig,
...requestConfig,
});
}

post(data: unknown, requestConfig?: AxiosRequestConfig) {
return this.api.post("", data, {
...HttpClient.clientConfig,
Expand All @@ -62,6 +55,13 @@ export class HttpClient {
});
}

search(data: unknown, requestConfig?: AxiosRequestConfig) {
return this.api.post("/search", data, {
...HttpClient.clientConfig,
...requestConfig,
});
}

delete(requestConfig?: AxiosRequestConfig) {
return this.api.delete("", {
...HttpClient.clientConfig,
Expand Down Expand Up @@ -97,6 +97,20 @@ export class HttpClient {
});
}

video(data: unknown, requestConfig?: AxiosRequestConfig) {
return this.api.post("/video", data, {
...HttpClient.clientConfig,
...requestConfig,
});
}

image(data: unknown, requestConfig?: AxiosRequestConfig) {
return this.api.post("/image", data, {
...HttpClient.clientConfig,
...requestConfig,
});
}

private setting() {
HttpClient.setCommonInterceptors(this.api);
}
Expand Down Expand Up @@ -136,6 +150,7 @@ export default {
memberName: new HttpClient("/api/member/name", axiosConfig),
comment: new HttpClient("/api/comment", axiosConfig),
file: new HttpClient("/api/file", axiosConfig),
fileUpload: new HttpClient("/api/file/upload", axiosConfig),
follow: new HttpClient("/api/follow", axiosConfig),
refreshToken: new HttpClient("/api/refresh-token", axiosConfig),
revalidatePortfolio: new HttpClient("/api/revalidate-portfolio", axiosConfig),
Expand Down
10 changes: 6 additions & 4 deletions components/app/PortfolioPlayer.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import useWindow from "@/hooks/useWindow";
import { PortfolioType } from "@/types/portfolio.interface";
import classNames from "classnames";
import { useEffect, useState } from "react";
import Button from "../atoms/Button";
import Video from "../atoms/Video";

interface PortfolioProps {
type: PortfolioType;
Expand All @@ -17,6 +19,8 @@ export default function PortfolioPlayer({
const [selected, setSelected] = useState<"web" | "video">(
type === "URL" ? "web" : "video",
);
const { isWindow } = useWindow();

useEffect(() => {
setSelected(type === "URL" ? "web" : "video");
}, [type]);
Expand Down Expand Up @@ -60,10 +64,8 @@ export default function PortfolioPlayer({
title="portfolio"
/>
)}
{selected === "video" && (
<video src={videoUrl} controls className="w-full">
<track default kind="captions" srcLang="ko" src={videoUrl} />
</video>
{selected === "video" && isWindow && (
<Video width="100%" height="auto" src={videoUrl} controls />
)}
</div>
);
Expand Down
93 changes: 22 additions & 71 deletions components/app/UploadModal/FileUploadView.tsx
Original file line number Diff line number Diff line change
@@ -1,65 +1,34 @@
import FileUploader from "@/components/atoms/FileUploader";
import DropFileUploader from "@/components/atoms/DropFileUploader";
import Input from "@/components/atoms/Input";
import { PortfolioForm } from "@/types/portfolio.interface";
import classNames from "classnames";
import Image from "next/image";
import { Dispatch, SetStateAction } from "react";
import { UseFormRegister } from "react-hook-form";

interface FileUploadViewProps {
register: UseFormRegister<PortfolioForm>;
className?: string;
setVideoFileList: Dispatch<SetStateAction<File[]>>;
setThumbnailFileList: Dispatch<SetStateAction<File[]>>;
}

export default function FileUploadView({
register,
className,
videoFile,
setVideoFile,
setThumbnailFile,
thumbnailFile,
setVideoFileList,
setThumbnailFileList,
...props
}: {
register: UseFormRegister<PortfolioForm>;
className?: string;
videoFile: File | undefined;
setVideoFile: Dispatch<SetStateAction<File | undefined>>;
thumbnailFile: File | undefined;
setThumbnailFile: Dispatch<SetStateAction<File | undefined>>;
}) {
const getFileUploaderBorderCss = () => {
return `
relative
border
mb-2.5
flex
flex-col
justify-center
items-center
border-primary-border_gray
gap-2.5
rounded-lg`;
};

}: FileUploadViewProps) {
return (
<div className={classNames("flex flex-col gap-8", className)} {...props}>
<div>
<h2 className="mb-2">동영상</h2>
<div
className={classNames("w-full h-[11rem]", getFileUploaderBorderCss())}
>
<FileUploader
id="video-uploader"
label="동영상 업로드"
onChange={(event) => {
if (event.target.files) setVideoFile(event.target.files[0]);
}}
/>
{videoFile && (
<video
src={URL.createObjectURL(videoFile)}
className="w-full h-44 -z-10 absolute object-cover rounded-lg opacity-30"
>
<track kind="captions" src={URL.createObjectURL(videoFile)} />
</video>
)}
</div>

<DropFileUploader
id="video"
setFileList={setVideoFileList}
label="동영상 드래그 앤 드롭으로 업로드"
accept="video"
/>
<div>
<h2 className="mb-2">웹 주소</h2>
<div className="w-full flex flex-col items-center border-primary-border_gray gap-2.5 rounded-lg">
Expand All @@ -72,29 +41,11 @@ export default function FileUploadView({
</div>

<h2 className="mt-5 mb-2">썸네일</h2>
<div
className={classNames(
"w-[20rem] h-[11.25rem]",
getFileUploaderBorderCss(),
)}
>
<FileUploader
id="thumbnail-uploader"
label="썸네일 업로드"
onChange={(event) => {
if (event.target.files) setThumbnailFile(event.target.files[0]);
}}
/>
{thumbnailFile && (
<Image
src={URL.createObjectURL(thumbnailFile)}
alt="ddd"
fill
sizes="20rem"
className="rounded-lg -z-10 opacity-30"
/>
)}
</div>
<DropFileUploader
id="thumbnail"
setFileList={setThumbnailFileList}
label="썸네일 드래그 앤 드롭으로 업로드"
/>
<span>이미지 사이즈: 1280x720 (너비 640px 이상)</span>
</div>
</div>
Expand Down
16 changes: 8 additions & 8 deletions components/app/UploadModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,20 @@ export default function UploadModal({ closeModal }: UploadModalProps) {
const [pageIndex, setPageIndex] = useState(0);
const [selectedSkills, setSelectedSkills] = useState<Skill[]>([]);
const [selectedMembers, setSelectedMembers] = useState<Member[]>([]);
const [thumbnailFile, setThumbnailFile] = useState<File>();
const [videoFile, setVideoFile] = useState<File>();
const [videoFileList, setVideoFileList] = useState<File[]>([]);
const [thumbnailFileList, setThumbnailFileList] = useState<File[]>([]);

const { register, handleSubmit, setValue } = useForm<PortfolioForm>();
const queryClient = useQueryClient();
const { openToast } = useOverlay();

const onValid: SubmitHandler<PortfolioForm> = async (data) => {
const videoFileUid =
videoFile && (await getFileUidByFileUpload(videoFile, openToast));
videoFileList.length &&
(await getFileUidByFileUpload(videoFileList[0], openToast, "video"));
const thumbnailFileUid =
thumbnailFile && (await getFileUidByFileUpload(thumbnailFile, openToast));
thumbnailFileList.length &&
(await getFileUidByFileUpload(thumbnailFileList[0], openToast, "image"));

const getPortfolioType = (): PortfolioType => {
if (data.portfolioUrl.length > 0 && videoFileUid) {
Expand Down Expand Up @@ -92,10 +94,8 @@ export default function UploadModal({ closeModal }: UploadModalProps) {
<FileUploadView
className={classNames({ hidden: pageIndex !== 0 })}
register={register}
videoFile={videoFile}
setVideoFile={setVideoFile}
thumbnailFile={thumbnailFile}
setThumbnailFile={setThumbnailFile}
setThumbnailFileList={setThumbnailFileList}
setVideoFileList={setVideoFileList}
/>
<FormView
className={classNames({ hidden: pageIndex !== 1 })}
Expand Down
93 changes: 93 additions & 0 deletions components/atoms/DropFileUploader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import useFileDrop from "@/hooks/useFileDrop";
import classNames from "classnames";
import Image from "next/image";
import {
Dispatch,
ReactNode,
SetStateAction,
useEffect,
useState,
} from "react";

type AcceptType = "image" | "video";
interface DropFileUploaderProps {
id?: string;
className?: string;
label?: string | ReactNode;
isSingleFile?: boolean;
accept?: AcceptType;
setFileList: Dispatch<SetStateAction<File[]>>;
}

export default function DropFileUploader({
id = "",
className = "",
label = "",
isSingleFile = true,
accept = "image",
setFileList,
}: DropFileUploaderProps) {
const [previewFile, setPreviewFile] = useState<File>();
const { files, inputRef, isDragActive, labelRef } = useFileDrop({
isSingleFile,
accept: accept === "video" ? "video/*" : "image/*",
});

const getFileUploaderBorderCss = () => {
return `
relative
border
mb-2.5
flex
flex-col
justify-center
items-center
gap-2.5
rounded-lg
cursor-pointer
`;
};

useEffect(() => {
setFileList(files);
setPreviewFile(files[0]);
}, [files, setFileList]);

return (
<label
htmlFor={id}
className={classNames(
className,
getFileUploaderBorderCss(),
"relative w-full h-[11rem]",
{
"!border-2 !border-blue border-dotted": isDragActive,
},
)}
ref={labelRef}
>
<input ref={inputRef} type="file" className="hidden" id={id} />

{label}

{previewFile && accept === "image" && (
<Image
src={URL.createObjectURL(previewFile)}
alt="썸네일"
fill
sizes="20rem"
className="rounded-lg -z-10 opacity-30"
/>
)}

{previewFile && accept === "video" && (
<video
src={URL.createObjectURL(previewFile)}
className="w-full h-44 -z-10 absolute object-cover rounded-lg opacity-30"
>
<track kind="captions" src={URL.createObjectURL(previewFile)} />
</video>
)}
</label>
);
}
7 changes: 5 additions & 2 deletions components/atoms/FileUploader.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import classNames from "classnames";
import { ChangeEventHandler, InputHTMLAttributes } from "react";
import { ChangeEventHandler, InputHTMLAttributes, RefObject } from "react";

type ButtonVarient = "primary" | "secondary";
interface FileUploaderProps extends InputHTMLAttributes<HTMLInputElement> {
Expand All @@ -8,6 +8,7 @@ interface FileUploaderProps extends InputHTMLAttributes<HTMLInputElement> {
label?: string;
varient?: ButtonVarient;
id?: string;
inputRef?: RefObject<HTMLInputElement>;
}

const getFileUploaderCss = (varient: ButtonVarient) => {
Expand All @@ -30,6 +31,7 @@ export default function FileUploader({
label,
className = "",
id = "file-uploader",
inputRef,
}: FileUploaderProps) {
return (
<>
Expand All @@ -40,9 +42,10 @@ export default function FileUploader({
{label}
</label>
<input
ref={inputRef}
type="file"
id={id}
className={classNames("hidden")}
className="hidden"
onChange={onChange}
/>
</>
Expand Down
3 changes: 2 additions & 1 deletion components/atoms/Radio.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import classNames from "classnames";
import { InputHTMLAttributes } from "react";
import { UseFormRegisterReturn } from "react-hook-form";

interface RadioProps {
interface RadioProps extends InputHTMLAttributes<HTMLInputElement> {
id: string;
label: string;
description?: string;
Expand Down
14 changes: 14 additions & 0 deletions components/atoms/Video.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import useWindow from "@/hooks/useWindow";
import { ReactPlayerProps } from "react-player";
import ReactPlayer from "react-player/lazy";

interface VideoProps extends ReactPlayerProps {
src?: string | string[];
}

export default function Video({ src, ...props }: VideoProps) {
const { isWindow } = useWindow();
if (!isWindow) return <div />;

return <ReactPlayer width="100%" url={src} {...props} />;
}
Loading

1 comment on commit 7153ffb

@vercel
Copy link

@vercel vercel bot commented on 7153ffb Mar 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.