Skip to content

Commit

Permalink
Merge pull request #179 from choco-team/178-fe-qrcode-페이지-타입-파일-구조-리팩터링
Browse files Browse the repository at this point in the history
[FE] qrcode 페이지 타입 파일 구조 리팩터링
  • Loading branch information
nlom0218 authored Mar 14, 2024
2 parents 3f975a7 + 6925d18 commit 2dc6bd8
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 78 deletions.
4 changes: 2 additions & 2 deletions src/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import SignIn from '@Pages/Auth/SignIn';
import SignUp from '@Pages/Auth/SignUp';
import LunchMenu from '@Pages/ClassManagement/LunchMenu';
import Home from '@Pages/Home';
import QrcodePage from '@Pages/Qrcode/QrcodePage';
import QrCode from '@Pages/QrCode';
import StudentManagement from '@Pages/StudentManagement';
import StudentInfo from '@Pages/StudentManagement/StudentInfo';
import StudentRegister from '@Pages/StudentManagement/StudentRegister';
Expand Down Expand Up @@ -104,7 +104,7 @@ const router = createBrowserRouter([
},
{
path: ROUTE_PATH.qrCode,
element: <QrcodePage />,
element: <QrCode />,
},
{
path: ROUTE_PATH.favorites,
Expand Down
22 changes: 9 additions & 13 deletions src/pages/Qrcode/QrcodeBlock/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import React, { useState } from 'react';

import * as S from './style';

const QrcodeBlock = () => {
const [isSelected, setIsSelected] = useState(false);

const toggleSelection = () => {
setIsSelected(!isSelected);
};
type QrCodeBlockProps = {
data: string;
isSelected: boolean;
onClick: () => void;
};

const QrCodeBlock = ({ data, isSelected, onClick }: QrCodeBlockProps) => {
return (
<S.Storage onClick={toggleSelection} isSelected={isSelected}>
<S.Storage onClick={onClick} $isSelected={isSelected}>
<S.ImageContainer>
<img
src="data:image/png;base64,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"
Expand All @@ -19,12 +17,10 @@ const QrcodeBlock = () => {
</S.ImageContainer>
<S.TextContainer>
<S.TextSpan>패들렛으로 만들었던 학생작품</S.TextSpan>
<S.TextSpan>
https://nyjyangji.padlet.org/soave4242/4-1-2-6tsejdfooh969wo3
</S.TextSpan>
<S.TextSpan>{data}</S.TextSpan>
</S.TextContainer>
</S.Storage>
);
};

export default QrcodeBlock;
export default QrCodeBlock;
8 changes: 6 additions & 2 deletions src/pages/Qrcode/QrcodeBlock/style.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import styled from 'styled-components';

export const Storage = styled.div`
background-color: ${(props) => (props.isSelected ? '#fee3e2' : 'white')};
type StorageProps = {
$isSelected: boolean;
};

export const Storage = styled.div<StorageProps>`
background-color: ${({ $isSelected }) => ($isSelected ? '#fee3e2' : 'white')};
cursor: pointer;
padding: 20px;
margin: 10px;
Expand Down
19 changes: 9 additions & 10 deletions src/pages/Qrcode/QrcodeInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import React, { useState } from 'react';
import useModal from '@Hooks/useModal';

import * as S from './style';
import QrcodeName from '../QrcodeName';
import QrcodePrintOption from '../QrcodePrintOption';
import QrCodeName from '../QrCodeName';
import QrCodePrintOption from '../QrCodePrintOption';

function QrcodeInput() {
function QrCodeInput() {
const [inputValue, setInputValue] = useState<string>('');

const { isOpen, openModal, closeModal } = useModal();
const { openModal } = useModal();

const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(event.target.value);
Expand All @@ -25,7 +25,7 @@ function QrcodeInput() {
const url = canvas ? canvas.toDataURL('image/png') : '';
const link = document.createElement('a');
link.href = url;
link.download = `qrcode.png`;
link.download = `qrCode.png`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
Expand All @@ -34,7 +34,7 @@ function QrcodeInput() {
const handleViewLarger = () => {
const canvas = document.querySelector('canvas');
const qrCodeDataURL = canvas ? canvas.toDataURL('image/png') : '';
const newWindow = window.open(qrCodeDataURL, 'qrcodePopup');
const newWindow = window.open(qrCodeDataURL, 'qrCodePopup');
if (newWindow) {
newWindow.document.write(`
<div style="display: flex; justify-content: center; align-items: center; height: 100vh;">
Expand Down Expand Up @@ -72,19 +72,18 @@ function QrcodeInput() {
{isButtonVisible && (
<S.ButtonContainer>
<S.Button onClick={handleViewLarger}>크게보기</S.Button>
<S.Button onClick={() => openModal(<QrcodePrintOption />)}>
<S.Button onClick={() => openModal(<QrCodePrintOption />)}>
인쇄하기
</S.Button>
<S.Button onClick={handleDownload}>다운로드</S.Button>
<S.Button onClick={handleGoToLink}>바로가기</S.Button>
<S.Button onClick={() => openModal(<QrcodeName />)}>
<S.Button onClick={() => openModal(<QrCodeName />)}>
보관함에 저장
</S.Button>
</S.ButtonContainer>
)}
{isOpen && <QrcodeName />}
</S.Container>
);
}

export default QrcodeInput;
export default QrCodeInput;
4 changes: 2 additions & 2 deletions src/pages/Qrcode/QrcodeName/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Input from '@Components/Input';

import * as S from './style';

const QrcodeName = () => {
const QrCodeName = () => {
return (
<S.Container>
<S.NameSpan>저장할 QR코드 이름</S.NameSpan>
Expand All @@ -13,4 +13,4 @@ const QrcodeName = () => {
);
};

export default QrcodeName;
export default QrCodeName;
12 changes: 6 additions & 6 deletions src/pages/Qrcode/QrcodePrintOption/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import useModal from '@Hooks/useModal';
import Button from '@Components/Button';

import * as S from './style';
import QrcodePrintPage from '../QrcodePrintPage';
import QrCodePrintPage from '../QrCodePrintPage';

const QrcodePrintOption: React.FC = () => {
const QrCodePrintOption: React.FC = () => {
const [selectedSize, setSelectedSize] = useState<string>('');
const { closeModal } = useModal();
const [number, setNumber] = useState<number>(0);
const componentRef = useRef();
const componentRef = useRef<HTMLDivElement>(null);

const handleChangeNumber = (e: React.ChangeEvent<HTMLInputElement>) => {
const newValue = parseInt(e.target.value, 10);
Expand All @@ -41,7 +41,7 @@ const QrcodePrintOption: React.FC = () => {
};

const handlePrintBtn = useReactToPrint({
content: () => componentRef.current,
content: () => componentRef.current!,
});
return (
<S.Container>
Expand Down Expand Up @@ -76,10 +76,10 @@ const QrcodePrintOption: React.FC = () => {
취소
</Button>
<Button onClick={handlePrintBtn}>인쇄</Button>
<QrcodePrintPage ref={componentRef} />
<QrCodePrintPage ref={componentRef} />
</S.SmallButtonWrapper>
</S.Container>
);
};

export default QrcodePrintOption;
export default QrCodePrintOption;
14 changes: 8 additions & 6 deletions src/pages/Qrcode/QrcodePrintPage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React, { useState } from 'react';
import { ForwardedRef, forwardRef } from 'react';

import * as S from './style';
const QrCodePrintPage = forwardRef(
(props = {}, ref: ForwardedRef<HTMLDivElement>) => {
return <div ref={ref}></div>;
},
);

function QrcodePrintPage() {
return;
}
QrCodePrintPage.displayName = 'QrCodePrintPage';

export default QrcodePrintPage;
export default QrCodePrintPage;
45 changes: 22 additions & 23 deletions src/pages/Qrcode/QrcodeStorage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { useState } from 'react'; // useState 추가
import { useState } from 'react'; // useState 추가

import * as S from './style';
import QrcodeBlock from '../QrcodeBlock';
import QrCodeBlock from '../QrCodeBlock';

function QrcodeStorage() {
const qrcodeData = [
function QrCodeStorage() {
const qrCodeData = [
{ id: 'qr1', url: 'https://example.com/qr1' },
{ id: 'qr2', url: 'https://example.com/qr2' },
{ id: 'qr3', url: 'https://example.com/qr3' },
Expand All @@ -15,18 +15,18 @@ function QrcodeStorage() {
{ id: 'qr8', url: 'https://example.com/qr8' },
];

const [selectedQrcodes, setSelectedQrcodes] = useState([]);
const [selectedQrCodes, setSelectedQrCodes] = useState<string[]>([]);

const toggleSelectAll = () => {
if (selectedQrcodes.length < qrcodeData.length) {
setSelectedQrcodes(qrcodeData.map((item) => item.id));
if (selectedQrCodes.length < qrCodeData.length) {
setSelectedQrCodes(qrCodeData.map((item) => item.id));
} else {
setSelectedQrcodes([]);
setSelectedQrCodes([]);
}
};

const toggleSelect = (id) => {
setSelectedQrcodes((prevSelected) =>
const toggleSelect = (id: string) => {
setSelectedQrCodes((prevSelected) =>
prevSelected.includes(id)
? prevSelected.filter((qrId) => qrId !== id)
: [...prevSelected, id],
Expand Down Expand Up @@ -58,8 +58,8 @@ function QrcodeStorage() {
<div style="display: flex; flex-wrap: wrap; justify-content: center; align-items: center; height: 100vh;">
`);

selectedQrcodes.forEach((selectedId) => {
const qrCodeItem = qrcodeData.find((item) => item.id === selectedId);
selectedQrCodes.forEach((selectedId) => {
const qrCodeItem = qrCodeData.find((item) => item.id === selectedId);
if (qrCodeItem) {
newWindow.document.write(`
<div style="margin: 10px;">
Expand All @@ -73,37 +73,36 @@ function QrcodeStorage() {
}
};

const handleDeleteQrcode = () => {
const handleDeleteQrCode = () => {
// 삭제하기 로직 구현
};

return (
<S.Container>
<S.ButtonContainer>
<S.SelectAllButton onClick={toggleSelectAll}>
{selectedQrcodes.length < qrcodeData.length
{selectedQrCodes.length < qrCodeData.length
? '전체 선택'
: '선택 해제'}
</S.SelectAllButton>
<S.Button onClick={handleViewLarger}>크게보기</S.Button>
<S.Button>인쇄하기</S.Button>
<S.Button onClick={handleDownload}>다운로드</S.Button>
<S.Button onClick={handleDeleteQrcode}>삭제하기</S.Button>
<S.Button onClick={handleDeleteQrCode}>삭제하기</S.Button>
</S.ButtonContainer>

<S.QrcodeBlockContainer>
{qrcodeData.map((item) => (
<QrcodeBlock
onClick={() => onToggle(data.id)}
<S.QrCodeBlockContainer>
{qrCodeData.map((item) => (
<QrCodeBlock
onClick={() => toggleSelect(item.id)}
key={item.id}
data={item.url}
isSelected={selectedQrcodes.includes(item.id)}
onToggle={() => toggleSelect(item.id)}
isSelected={selectedQrCodes.includes(item.id)}
/>
))}
</S.QrcodeBlockContainer>
</S.QrCodeBlockContainer>
</S.Container>
);
}

export default QrcodeStorage;
export default QrCodeStorage;
2 changes: 1 addition & 1 deletion src/pages/Qrcode/QrcodeStorage/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const StorageButton = styled.div`
}
`;

export const QrcodeBlockContainer = styled.div`
export const QrCodeBlockContainer = styled.div`
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 20px;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { useState } from 'react';
import { useState } from 'react';

import QrCodeInput from './QrCodeInput';
import QrCodeStorage from './QrCodeStorage';
import * as S from './style';
import QrcodeInput from '../QrcodeInput';
import QrcodeStorage from '../QrcodeStorage';

function QrcodePage() {
function QrCode() {
const [isInStorageMode, setIsInStorageMode] = useState(false);
const handleToStorage = () => {
setIsInStorageMode(!isInStorageMode); // isInStorageMode 상태 토글
Expand All @@ -17,16 +17,9 @@ function QrcodePage() {
{isInStorageMode ? '새 QR 코드 생성' : '보관함'}
</S.StorageButton>

{isInStorageMode ? (
<QrcodeStorage
isInStorageMode={isInStorageMode}
setIsInStorageMode={setIsInStorageMode}
/>
) : (
<QrcodeInput />
)}
{isInStorageMode ? <QrCodeStorage /> : <QrCodeInput />}
</S.Container>
);
}

export default QrcodePage;
export default QrCode;
File renamed without changes.

0 comments on commit 2dc6bd8

Please sign in to comment.