Merge branch 'fe/develop' into fe/design/footer-and-home
This commit is contained in:
commit
bfa5ba0125
31
frontend/src/components/Footer/Modal.tsx
Normal file
31
frontend/src/components/Footer/Modal.tsx
Normal file
@ -0,0 +1,31 @@
|
||||
import { Dialog, DialogContent, DialogOverlay, DialogTitle, DialogClose } from '@radix-ui/react-dialog';
|
||||
import { X } from 'lucide-react';
|
||||
|
||||
interface ModalProps {
|
||||
title: string;
|
||||
content: React.ReactNode;
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export default function Modal({ title, content, open, onClose }: ModalProps) {
|
||||
return (
|
||||
<Dialog
|
||||
open={open}
|
||||
onOpenChange={onClose}
|
||||
>
|
||||
<DialogOverlay className="fixed inset-0 bg-black/50" />
|
||||
<DialogContent className="fixed left-1/2 top-1/2 w-[90%] max-w-lg -translate-x-1/2 -translate-y-1/2 transform rounded-lg bg-white p-6 shadow-lg">
|
||||
<div className="flex items-center justify-between">
|
||||
<DialogTitle className="text-xl font-bold">{title}</DialogTitle>
|
||||
<DialogClose asChild>
|
||||
<button className="text-gray-500 hover:text-black">
|
||||
<X size={24} />
|
||||
</button>
|
||||
</DialogClose>
|
||||
</div>
|
||||
<div className="mt-4">{content}</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
@ -1,21 +1,150 @@
|
||||
import { Link } from 'react-router-dom';
|
||||
import * as React from 'react';
|
||||
import Modal from './Modal';
|
||||
import { cn } from '@/lib/utils';
|
||||
export interface FooterProps extends React.HTMLAttributes<HTMLDivElement> {}
|
||||
|
||||
export default function Footer({ className, ...props }: FooterProps) {
|
||||
const [isTermsOpen, setIsTermsOpen] = React.useState(false);
|
||||
const [isPrivacyOpen, setIsPrivacyOpen] = React.useState(false);
|
||||
|
||||
export default function Footer() {
|
||||
return (
|
||||
<footer className="select-none bg-gray-100">
|
||||
<div className="container py-8 text-gray-400">
|
||||
<div className="body-small flex flex-col items-start gap-5">
|
||||
<div>
|
||||
<div className="heading">WorLabel</div>
|
||||
<span>Copyright © 2024 WorLabel. All rights reserved.</span>
|
||||
<footer
|
||||
className={cn('mt-[100px] border-t border-gray-200 bg-gray-100', className)}
|
||||
{...props}
|
||||
>
|
||||
{' '}
|
||||
<div className="container py-10">
|
||||
<div className="flex flex-col items-start gap-5">
|
||||
<div className="relative">
|
||||
<div className="font-heading text-lg text-gray-600 md:text-xl">WorLabel</div>
|
||||
<p className="font-body-small mt-2 text-gray-500">Copyright © 2024 WorLabel All rights reserved</p>
|
||||
</div>
|
||||
<div className="inline-flex items-center gap-2">
|
||||
<Link to="#">서비스 이용약관</Link>
|
||||
<span className="h-3 w-px rounded bg-gray-400" />
|
||||
<Link to="#">개인정보 처리방침</Link>
|
||||
<div className="inline-flex items-center gap-4">
|
||||
<button
|
||||
className="font-body-small text-gray-500 hover:text-primary"
|
||||
onClick={() => setIsTermsOpen(true)}
|
||||
>
|
||||
서비스 이용약관
|
||||
</button>
|
||||
<div className="h-4 w-px bg-gray-400" />
|
||||
<button
|
||||
className="font-body-small text-gray-500 hover:text-primary"
|
||||
onClick={() => setIsPrivacyOpen(true)}
|
||||
>
|
||||
개인정보 처리방침
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Terms of Service Modal */}
|
||||
<Modal
|
||||
title="서비스 이용약관"
|
||||
content={
|
||||
<>
|
||||
<p>
|
||||
<strong>제1조 목적</strong>
|
||||
</p>
|
||||
<p>
|
||||
이 약관은 WorLabel(이하 "회사")이 제공하는 모든 서비스(이하 "서비스")의 이용과 관련된 사항을 규정하는 것을
|
||||
목적으로 합니다.
|
||||
</p>
|
||||
<br />
|
||||
<p>
|
||||
<strong>제2조 정의</strong>
|
||||
</p>
|
||||
<p>
|
||||
1. "서비스"란 회사가 제공하는 모든 온라인 콘텐츠와 기능을 의미합니다.
|
||||
<br />
|
||||
2. "회원"이란 회사의 서비스에 접속하여 본 약관에 동의한 자를 말합니다.
|
||||
</p>
|
||||
<br />
|
||||
<p>
|
||||
<strong>제3조 약관의 효력 및 변경</strong>
|
||||
</p>
|
||||
<p>
|
||||
1. 본 약관은 서비스 화면에 공지되며, 회원이 약관에 동의한 시점부터 효력이 발생합니다.
|
||||
<br />
|
||||
2. 회사는 필요에 따라 본 약관을 변경할 수 있으며, 변경된 약관은 서비스 화면에 공지됩니다.
|
||||
</p>
|
||||
<br />
|
||||
<p>
|
||||
<strong>제4조 서비스 이용</strong>
|
||||
</p>
|
||||
<p>
|
||||
1. 회원은 회사가 제공하는 서비스를 본 약관에 따라 이용할 수 있습니다.
|
||||
<br />
|
||||
2. 회사는 서비스의 운영 또는 기술적 필요에 따라 서비스의 전부 또는 일부를 변경할 수 있습니다.
|
||||
</p>
|
||||
<br />
|
||||
<p>
|
||||
<strong>제5조 회원의 의무</strong>
|
||||
</p>
|
||||
<p>
|
||||
1. 회원은 서비스 이용 시 본 약관을 준수해야 하며, 법령을 위반하는 행위를 해서는 안 됩니다.
|
||||
<br />
|
||||
2. 회원은 타인의 개인정보를 침해하거나, 서비스의 안정적 운영을 방해하는 행위를 해서는 안 됩니다.
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
open={isTermsOpen}
|
||||
onClose={() => setIsTermsOpen(false)}
|
||||
/>
|
||||
{/* Privacy Policy Modal */}
|
||||
<Modal
|
||||
title="개인정보 처리방침"
|
||||
content={
|
||||
<>
|
||||
<p>
|
||||
<strong>제1조 수집하는 개인정보의 항목</strong>
|
||||
</p>
|
||||
<p>
|
||||
1. 회사는 서비스 제공을 위해 필요한 최소한의 개인정보를 수집합니다.
|
||||
<br />
|
||||
2. 수집하는 개인정보 항목은 다음과 같습니다: 이름, 이메일, 서비스 이용 기록, 접속 로그, 쿠키 등.
|
||||
</p>
|
||||
<br />
|
||||
<p>
|
||||
<strong>제2조 개인정보의 수집 및 이용 목적</strong>
|
||||
</p>
|
||||
<p>
|
||||
1. 회사는 다음의 목적을 위해 개인정보를 수집 및 이용합니다:
|
||||
<br />
|
||||
- 회원관리, 서비스 제공, 계약 이행 및 요금 정산.
|
||||
<br />
|
||||
2. 서비스 개선 및 맞춤형 서비스 제공을 위해 활용될 수 있습니다.
|
||||
</p>
|
||||
<br />
|
||||
<p>
|
||||
<strong>제3조 개인정보의 보유 및 이용 기간</strong>
|
||||
</p>
|
||||
<p>
|
||||
1. 회원의 개인정보는 회원 탈퇴 시 지체 없이 파기됩니다.
|
||||
<br />
|
||||
2. 단, 관계 법령에 따라 일정 기간 보관해야 하는 경우 해당 기간 동안 보유합니다.
|
||||
</p>
|
||||
<br />
|
||||
<p>
|
||||
<strong>제4조 개인정보의 제3자 제공</strong>
|
||||
</p>
|
||||
<p>
|
||||
1. 회사는 원칙적으로 회원의 동의 없이 개인정보를 외부에 제공하지 않습니다.
|
||||
<br />
|
||||
2. 다만, 법령에 의해 요구되는 경우나 회원의 사전 동의를 받은 경우에 한해 제공됩니다.
|
||||
</p>
|
||||
<br />
|
||||
<p>
|
||||
<strong>제5조 회원의 권리와 행사 방법</strong>
|
||||
</p>
|
||||
<p>
|
||||
1. 회원은 언제든지 자신의 개인정보를 조회하거나 수정할 수 있으며, 개인정보의 삭제를 요청할 수 있습니다.
|
||||
<br />
|
||||
2. 회원은 개인정보의 처리에 관한 동의를 철회할 수 있습니다.
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
open={isPrivacyOpen}
|
||||
onClose={() => setIsPrivacyOpen(false)}
|
||||
/>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
|
@ -148,8 +148,7 @@ export default function ImagePreSignedForm({
|
||||
onProgress: (progress) => {
|
||||
setUploadStatus((prevStatus) => {
|
||||
const completedFiles = Math.round((progress / 100) * files.length);
|
||||
const newStatus = prevStatus.map((status, index) => (index < completedFiles ? 'success' : status));
|
||||
return newStatus;
|
||||
return prevStatus.map((status, index) => (index < completedFiles ? 'success' : status));
|
||||
});
|
||||
},
|
||||
useSingleUpload: uploadType === 'file',
|
||||
@ -166,7 +165,7 @@ export default function ImagePreSignedForm({
|
||||
}
|
||||
};
|
||||
|
||||
const totalProgress = Math.round((uploadStatus.filter((status) => status !== null).length / files.length) * 100);
|
||||
const totalProgress = Math.round((uploadStatus.filter((status) => status === 'success').length / files.length) * 100);
|
||||
|
||||
useEffect(() => {
|
||||
onFileCount(files.length);
|
||||
|
@ -42,7 +42,6 @@ export default function Home() {
|
||||
asChild
|
||||
variant="blue"
|
||||
size="lg"
|
||||
className="mt-8"
|
||||
>
|
||||
<Link to="/browse">시작하기</Link>
|
||||
</Button>
|
||||
|
Loading…
Reference in New Issue
Block a user