From b131782a77f24f3d4b2ef3dcd8053d938c535b83 Mon Sep 17 00:00:00 2001 From: jinhojang6 Date: Tue, 1 Oct 2024 22:25:27 +0900 Subject: [PATCH] chore: update dropdown --- public/assets/download.svg | 5 + .../OperatorDetails/DownloadDropdown.tsx | 195 ++++++++++++++++++ .../OperatorDetails/OperatorDetails.tsx | 20 +- src/pages/_app.tsx | 4 +- 4 files changed, 213 insertions(+), 11 deletions(-) create mode 100644 public/assets/download.svg create mode 100644 src/components/Operator/OperatorDetails/DownloadDropdown.tsx diff --git a/public/assets/download.svg b/public/assets/download.svg new file mode 100644 index 0000000..28298fc --- /dev/null +++ b/public/assets/download.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/components/Operator/OperatorDetails/DownloadDropdown.tsx b/src/components/Operator/OperatorDetails/DownloadDropdown.tsx new file mode 100644 index 0000000..eaae3d1 --- /dev/null +++ b/src/components/Operator/OperatorDetails/DownloadDropdown.tsx @@ -0,0 +1,195 @@ +import styled from '@emotion/styled' +import Image from 'next/image' +import { useState } from 'react' + +interface Props { + operator: any +} + +function updateImageUrl(inputUrl: string): string { + const urlParts = inputUrl.split('/') + + if (urlParts.length > 4 && urlParts[4] === '400') { + urlParts[4] = '1024' + } + + return urlParts.join('/') +} + +const DownloadDropdown = ({ operator }: Props) => { + const [isOpen, setIsOpen] = useState(false) + + const toggleDropdown = () => { + setIsOpen((prev) => !prev) + } + + return ( + + + Download + + Chevron + + + + + + + Download + + Low Resolution + + .gif + + + + + Download + + High Resolution + + .gif + + + + + Download + + Low Resolution + + .jpeg + + + + + Download + + High Resolution + + .jpeg + + + + ) +} + +// Styled Components +const DropdownWrapper = styled.div` + position: relative; + display: flex; + flex-direction: column; + width: 100%; +` + +const DropdownButton = styled.button<{ isOpen: boolean }>` + padding: 10px 20px; + height: 40px; + border-left: none; + border-right: 1px solid #fff !important; + border-top: 1px solid #fff; + border-bottom: 1px solid #fff; + background: transparent; + position: relative; + + width: 100%; + color: #fff; + display: flex; + align-items: center; + justify-content: space-between; + + cursor: pointer; + + & > span { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-size: 14px; + font-weight: 400; + line-height: 20px; + letter-spacing: 0.14px; + } +` + +const ChevronIconWrapper = styled.div<{ isOpen: boolean }>` + display: flex; + position: absolute; + right: 14px; + align-items: center; + justify-content: center; + transition: transform 0.3s ease; + transform: ${({ isOpen }) => (isOpen ? 'rotate(180deg)' : 'rotate(0deg)')}; +` + +const DropdownContent = styled.div<{ isOpen: boolean }>` + display: ${({ isOpen }) => (isOpen ? 'flex' : 'none')}; + flex-direction: column; + box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); + z-index: 1; + border-left: 1px solid #fff; + margin-left: -1px; +` + +const DropdownItem = styled.a` + color: #fff !important; + padding: 12px 16px; + text-decoration: none; + display: flex; + align-items: center; + font-size: 12px; + line-height: 16px; + justify-content: space-between; + border-bottom: 1px solid #fff; + border-right: 1px solid #fff; + + &:hover { + color: #fff; + } +` + +const Left = styled.div` + display: flex; + align-items: center; +` + +const Icon = styled.span` + margin-right: 8px; + display: flex; + align-items: center; + gap: 16px; + * { + color: #fff; + } +` + +const FileType = styled.span` + font-size: 12px; + line-height: 16px; +` + +export default DownloadDropdown diff --git a/src/components/Operator/OperatorDetails/OperatorDetails.tsx b/src/components/Operator/OperatorDetails/OperatorDetails.tsx index 1f70dc6..2d9289f 100644 --- a/src/components/Operator/OperatorDetails/OperatorDetails.tsx +++ b/src/components/Operator/OperatorDetails/OperatorDetails.tsx @@ -4,6 +4,7 @@ import 'lazysizes' import React from 'react' import operators from '../../../../data/operators.json' import { findOperatorById, processOperators } from '../../../../utils/operators' +import DownloadDropdown from './DownloadDropdown' interface OperatorDetailsProps { id: number @@ -36,10 +37,6 @@ const OperatorDetails: React.FC = ({ const operator = findOperatorById(processedOperators, id) - const handleDownload = () => { - window.open(`/dashboard/mock/operators/${id % 7}.gif`, '_blank') - } - const handleShare = async () => { if (navigator.share) { try { @@ -68,7 +65,7 @@ const OperatorDetails: React.FC = ({ /> - + @@ -135,7 +132,7 @@ const Container = styled.section` const OperatorImage = styled.div` position: relative; - img { + & > img { width: 100%; height: auto; min-height: 400px; @@ -158,17 +155,22 @@ const OperatorInfo = styled.div` const ActionButtons = styled.div` display: flex; - gap: -1px; margin-top: 16px; - button:first-of-type { + width: 100%; + + & > * { + flex: 1; + } + + * > button:first-of-type { border-right: none; } ` const Button = styled.button` flex: 1; - padding: 10px 40px; + height: 40px; border: 1px solid #fff; background: transparent; color: #fff; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index c79c2a0..07f7702 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -83,13 +83,13 @@ export default function App({ Component, pageProps }: AppLayoutProps) { margin-right: auto; } - a, + /* a, a:visited, a:hover, a:active, a:focus { color: black; - } + } */ h1, h2,