Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT] Design 테스트 페이지 구현 #50

Merged
merged 7 commits into from
May 18, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/assets/icons/add.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions src/assets/icons/instagram.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
298 changes: 244 additions & 54 deletions src/components/DesignTest/DesignButtonView.tsx
Original file line number Diff line number Diff line change
@@ -1,136 +1,326 @@
import { useEffect, useState } from 'react';

import { useNavigate } from 'react-router-dom';
import { useRecoilState, useSetRecoilState } from 'recoil';
import styled from 'styled-components';

import { personaAPI } from '@/apis/personaAPI';
import { PlainButton } from '@/components/common/Button/PlainButton';
import { loadingHandlerState } from '@/recoil/loadingHandlerState';
import { loadingState } from '@/recoil/loadingState';
import { userService } from '@/services/UserService';

interface Props {
warning?: boolean;
warningMessage?: boolean;
}

const Container = styled.div`
position: relative;
width: 100%;
height: 100%;

display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
gap: 15px;
display: inline-flex;
`;

const ButtonContainer = styled.div`
justify-content: center;
align-items: flex-start;
width: 100%;
display: flex;
gap: 15px;
display: inline-flex;

@media ${({ theme }) => theme.device.tablet} {
gap: 8px;
}

@media ${({ theme }) => theme.device.mobile} {
gap: 8px;
}
`;
const ButtonInnerContainer = styled.div`
justify-content: center;
align-items: flex-start;
gap: 15px;
display: inline-flex;

const ChipContainer = styled.div`
position: absolute;

top: -16px;
left: 50%;

transform: translate(-50%, -100%);

width: max-content;
padding: 8px 20px;
border-radius: 8px;
border: 1px solid ${({ theme }) => `${theme.color.secondary600}`};
background: ${({ theme }) => `${theme.color.secondary50}`};

color: ${({ theme }) => `${theme.color.secondary600}`};
${({ theme }) => theme.font.desktop.label1m};
`;

const Text = styled.div`
color: ${({ theme }) => `${theme.color.gray400}`};
${({ theme }) => theme.font.desktop.label1m};
word-wrap: break-word;
`;

export const DesignButtonView1 = () => {
export const DesignButtonView1 = ({ warning, warningMessage }: Props) => {
const navigate = useNavigate();
const [showWarn, setShowWarn] = useState(false);

const handleButtonClick = () => {
navigate('/test/Design/2');
navigate('/test/design/2');
};

useEffect(() => {
if (warningMessage) {
setShowWarn(true);
const timer = setTimeout(() => {
setShowWarn(false);
}, 5000);

return () => clearTimeout(timer);
} else {
setShowWarn(false);
}
}, [warningMessage]);

return (
<Container>
<ButtonContainer>
<PlainButton variant="gray" height="48px" width="582px" onClick={handleButtonClick}>
다음으로
</PlainButton>
</ButtonContainer>
{showWarn && <ChipContainer>키워드를 3개 이하로 선택해 주세요!</ChipContainer>}
<PlainButton
variant="gray"
height="48px"
width="100%"
onClick={handleButtonClick}
disabled={warning}
>
다음으로
</PlainButton>
<Text>종료하기를 누르면 해당 단계부터 이어서 검사를 진행할 수 있어요!</Text>
</Container>
);
};

export const DesignButtonView2 = () => {
export const DesignButtonView2 = ({ warning, warningMessage }: Props) => {
const navigate = useNavigate();
const [showWarn, setShowWarn] = useState(false);

const handleButton1Click = () => {
navigate('/test/Design/1');
navigate('/test/design/1');
};

const handleButton2Click = () => {
navigate('/test/Design/3');
navigate('/test/design/3');
};

useEffect(() => {
if (warningMessage) {
setShowWarn(true);
const timer = setTimeout(() => {
setShowWarn(false);
}, 5000);

return () => clearTimeout(timer);
} else {
setShowWarn(false);
}
}, [warningMessage]);

return (
<Container>
{showWarn && <ChipContainer>키워드를 3개 이하로 선택해 주세요!</ChipContainer>}
<ButtonContainer>
<ButtonInnerContainer>
<PlainButton variant="gray" height="48px" width="232px" onClick={handleButton1Click}>
이전으로
</PlainButton>
<PlainButton variant="gray" height="48px" width="232px" onClick={handleButton2Click}>
다음으로
</PlainButton>
</ButtonInnerContainer>
<PlainButton variant="gray" height="48px" width="100%" onClick={handleButton1Click}>
이전으로
</PlainButton>
<PlainButton
variant="gray"
height="48px"
width="100%"
onClick={handleButton2Click}
disabled={warning}
>
다음으로
</PlainButton>
</ButtonContainer>
<Text>종료하기를 누르면 해당 단계부터 이어서 검사를 진행할 수 있어요!</Text>
</Container>
);
};

export const DesignButtonView3 = () => {
export const DesignButtonView3 = ({ warning, warningMessage }: Props) => {
const navigate = useNavigate();
const [showWarn, setShowWarn] = useState(false);

const handleButton1Click = () => {
navigate('/test/Design/2');
navigate('/test/design/2');
};

const handleButton2Click = () => {
navigate('/test/Design/4');
navigate('/test/design/4');
};

useEffect(() => {
if (warningMessage) {
setShowWarn(true);
const timer = setTimeout(() => {
setShowWarn(false);
}, 5000);

return () => clearTimeout(timer);
} else {
setShowWarn(false);
}
}, [warningMessage]);

return (
<Container>
{showWarn && <ChipContainer>키워드를 5개 이하로 선택해 주세요!</ChipContainer>}
<ButtonContainer>
<ButtonInnerContainer>
<PlainButton variant="gray" height="48px" width="232px" onClick={handleButton1Click}>
이전으로
</PlainButton>
<PlainButton variant="gray" height="48px" width="232px" onClick={handleButton2Click}>
다음으로
</PlainButton>
</ButtonInnerContainer>
<PlainButton variant="gray" height="48px" width="100%" onClick={handleButton1Click}>
이전으로
</PlainButton>
<PlainButton
variant="gray"
height="48px"
width="100%"
onClick={handleButton2Click}
disabled={warning}
>
다음으로
</PlainButton>
</ButtonContainer>
<Text>종료하기를 누르면 해당 단계부터 이어서 검사를 진행할 수 있어요!</Text>
</Container>
);
};

export const DesignButtonView4 = () => {
export const DesignButtonView4 = ({ warning, warningMessage }: Props) => {
const navigate = useNavigate();
const [showWarn, setShowWarn] = useState(false);

const handleButton1Click = () => {
navigate('/test/Design/3');
navigate('/test/design/3');
};

const handleButton2Click = () => {
navigate('/test/Design/5');
navigate('/test/design/5');
};

useEffect(() => {
if (warningMessage) {
setShowWarn(true);
const timer = setTimeout(() => {
setShowWarn(false);
}, 5000);

return () => clearTimeout(timer);
} else {
setShowWarn(false);
}
}, [warningMessage]);

return (
<Container>
{showWarn && <ChipContainer>플랫폼을 2개 이하로 선택해 주세요!</ChipContainer>}
<ButtonContainer>
<ButtonInnerContainer>
<PlainButton variant="gray" height="48px" width="232px" onClick={handleButton1Click}>
이전으로
</PlainButton>
<PlainButton variant="gray" height="48px" width="232px" onClick={handleButton2Click}>
다음으로
</PlainButton>
</ButtonInnerContainer>
<PlainButton variant="gray" height="48px" width="100%" onClick={handleButton1Click}>
이전으로
</PlainButton>
<PlainButton
variant="gray"
height="48px"
width="100%"
onClick={handleButton2Click}
disabled={warning}
>
다음으로
</PlainButton>
</ButtonContainer>
<Text>종료하기를 누르면 해당 단계부터 이어서 검사를 진행할 수 있어요!</Text>
</Container>
);
};

export const DesignButtonView5 = () => {
export const DesignButtonView5 = ({ warning, warningMessage }: Props) => {
const navigate = useNavigate();
const [showWarn, setShowWarn] = useState(false);
const setLoading = useSetRecoilState(loadingState);
const [loadingHandler, setLoadingHandler] = useRecoilState(loadingHandlerState);

const handleButton1Click = () => {
navigate('/test/design/4');
};

const handleButton2Click = () => {
const selectedChips1 = JSON.parse(sessionStorage.getItem('selectedChips1') || '[]');
const selectedChips2 = JSON.parse(sessionStorage.getItem('selectedChips2') || '[]');
const selectedChips3 = JSON.parse(sessionStorage.getItem('selectedChips3') || '[]');
const selectedChips4 = JSON.parse(sessionStorage.getItem('selectedChips4') || '[]');
const selectedChips5 = JSON.parse(sessionStorage.getItem('selectedChips5') || '[]');
console.log(selectedChips1, selectedChips2, selectedChips3, selectedChips4, selectedChips5);

const requestData = {
stage_one_keywords: selectedChips1,
stage_two_keywords: selectedChips2,
stage_three_keywords: selectedChips3,
stage_four_keywords: selectedChips4,
stage_five_keywords: selectedChips5,
};

setLoading(true);

personaAPI
.register(userService.getUserState() === 'MEMBER', requestData)
.then((response) => {
const { code, message, payload } = response;

if (code === '201') {
console.log('페르소나 생성 성공');
setLoadingHandler({
...loadingHandler,
handleCompleted: () => {
navigate(`/test/design/${payload.Design_persona_id}`);
},
});
} else {
console.error('페르소나 생성 실패:', message);
}
})
.catch((error) => {
console.error('페르소나 생성 요청 실패:', error);
window.alert('페르소나 생성 요청 실패');
});
};

useEffect(() => {
if (warningMessage) {
setShowWarn(true);
const timer = setTimeout(() => {
setShowWarn(false);
}, 5000);

return () => clearTimeout(timer);
}
}, [warningMessage]);

return (
<Container>
{showWarn && <ChipContainer>키워드를 1개만 선택해 주세요!</ChipContainer>}
<ButtonContainer>
<PlainButton variant="gray" height="48px" width="582px">
<PlainButton variant="gray" height="48px" width="100%" onClick={handleButton1Click}>
이전으로
</PlainButton>
<PlainButton
variant="primary2"
height="48px"
width="100%"
onClick={handleButton2Click}
disabled={warning}
>
결과 확인하기
</PlainButton>
</ButtonContainer>
<Text>종료하기를 누르면 해당 단계부터 이어서 검사를 진행할 수 있어요!</Text>
</Container>
);
};
386 changes: 332 additions & 54 deletions src/components/DesignTest/DesignChip.tsx

Large diffs are not rendered by default.

147 changes: 66 additions & 81 deletions src/components/DesignTest/DesignTestView.tsx
Original file line number Diff line number Diff line change
@@ -1,125 +1,110 @@
import styled from 'styled-components';

import { SectionContainer } from '@/styles';

import {
DesignButtonView1,
DesignButtonView2,
DesignButtonView3,
DesignButtonView4,
DesignButtonView5,
} from './DesignButtonView';
import { DesignChips1 } from './DesignChip';
DesignChips1,
DesignChips2,
DesignChips3,
DesignChips4,
DesignChips5,
} from '@/components/DesignTest/DesignChip';
import {
DesignTextView1,
DesignTextView2,
DesignTextView3,
DesignTextView4,
DesignTextView5,
} from './DesignTextView';

const StyledSectionContainer = styled(SectionContainer)`
padding: 64px;
padding-top: 140px;
} from '@/components/DesignTest/DesignTextView';

const StyledContainer = styled.section`
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
overflow: hidden;
`;

const StyledContainer = styled.section`
background: ${({ theme }) => `${theme.color.primary50}`};
min-height: 100vh;
padding: 118px 0 48px 0;
@media ${({ theme }) => theme.device.tablet} {
padding: 24px;
padding-top: 100px;
}
@media ${({ theme }) => theme.device.mobile} {
padding: 20px;
padding-top: 96px;
}
`;

const Container = styled.div`
width: 100%;
const StyledContentContainer = styled.div`
width: 632px;
height: 100%;
margin: 0 auto;
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
gap: 102px;
display: inline-flex;
@media ${({ theme }) => theme.device.tablet} {
width: 552px;
}
@media ${({ theme }) => theme.device.mobile} {
width: 100%;
}
`;

export const DesignTestView1 = () => {
return (
<>
<StyledContainer>
<StyledSectionContainer>
<Container>
<DesignTextView1 />
<DesignChips1 />
<DesignButtonView1 />
</Container>
</StyledSectionContainer>
</StyledContainer>
</>
<StyledContainer>
<StyledContentContainer>
<DesignTextView1 />
<DesignChips1 />
</StyledContentContainer>
</StyledContainer>
);
};

export const DesignTestView2 = () => {
return (
<>
<StyledContainer>
<StyledSectionContainer>
<Container>
<DesignTextView2 />
<DesignChips1 />
<DesignButtonView2 />
</Container>
</StyledSectionContainer>
</StyledContainer>
</>
<StyledContainer>
<StyledContentContainer>
<DesignTextView2 />
<DesignChips2 />
</StyledContentContainer>
</StyledContainer>
);
};

export const DesignTestView3 = () => {
return (
<>
<StyledContainer>
<StyledSectionContainer>
<Container>
<DesignTextView3 />
<DesignChips1 />
<DesignButtonView3 />
</Container>
</StyledSectionContainer>
</StyledContainer>
</>
<StyledContainer>
<StyledContentContainer>
<DesignTextView3 />
<DesignChips3 />
</StyledContentContainer>
</StyledContainer>
);
};

export const DesignTestView4 = () => {
return (
<>
<StyledContainer>
<StyledSectionContainer>
<Container>
<DesignTextView4 />
<DesignChips1 />
<DesignButtonView4 />
</Container>
</StyledSectionContainer>
</StyledContainer>
</>
<StyledContainer>
<StyledContentContainer>
<DesignTextView4 />
<DesignChips4 />
</StyledContentContainer>
</StyledContainer>
);
};

export const DesignTestView5 = () => {
return (
<>
<StyledContainer>
<StyledSectionContainer>
<Container>
<DesignTextView5 />
<DesignChips1 />
<DesignButtonView5 />
</Container>
</StyledSectionContainer>
</StyledContainer>
</>
<StyledContainer>
<StyledContentContainer>
<DesignTextView5 />
<DesignChips5 />
</StyledContentContainer>
</StyledContainer>
);
};
167 changes: 70 additions & 97 deletions src/components/DesignTest/DesignTextView.tsx
Original file line number Diff line number Diff line change
@@ -3,61 +3,68 @@ import styled from 'styled-components';
import ProgressBar from '@/components/common/ProgressBar';

const TextContainer = styled.div`
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
gap: 32px;
display: inline-flex;
gap: 24px;
`;
const InnerContainer = styled.div`
align-self: stretch;
height: 82px;
flex-direction: column;
justify-content: flex-start;
align-items: center;
gap: 32px;
width: 100%;
display: flex;
`;
const KeywordContainer = styled.div`
align-self: stretch;
height: 45px;
flex-direction: column;
justify-content: flex-start;
align-items: center;
gap: 8px;
`;
const KeywordContainer = styled.div`
display: flex;
flex-direction: column;
gap: 4px;
`;

const KeywordTitle = styled.div`
text-align: center;
color: ${({ theme }) => `${theme.color.gray900}`};
${({ theme }) => theme.font.desktop.body1b};
word-wrap: break-word;
@media ${({ theme }) => theme.device.tablet} {
${({ theme }) => theme.font.mobile.body1b};
}
@media ${({ theme }) => theme.device.mobile} {
${({ theme }) => theme.font.mobile.body1b};
}
`;

const KeywordDescription = styled.div`
text-align: center;
color: ${({ theme }) => `${theme.color.gray600}`};
${({ theme }) => theme.font.desktop.body1m};
word-wrap: break-word;
`;
${({ theme }) => theme.font.desktop.body2m};
const KeywordCount = styled.span`
color: ${({ theme }) => `${theme.color.primary500}`};
${({ theme }) => theme.font.desktop.body1m};
word-wrap: break-word;
@media ${({ theme }) => theme.device.tablet} {
${({ theme }) => theme.font.mobile.body2m};
}
@media ${({ theme }) => theme.device.mobile} {
${({ theme }) => theme.font.mobile.body2m};
}
.highlight {
color: ${({ theme }) => `${theme.color.primary500}`};
}
`;

const ProgressWrapper = styled.div`
justify-content: flex-start;
align-items: flex-start;
display: flex;
gap: 4px;
display: inline-flex;
`;

const ProgressText = styled.div`
${({ theme }) => theme.font.desktop.body1b};
@media ${({ theme }) => theme.device.tablet} {
${({ theme }) => theme.font.mobile.body1b};
}
@media ${({ theme }) => theme.device.mobile} {
${({ theme }) => theme.font.mobile.body1b};
}
word-wrap: break-word;
`;

@@ -68,20 +75,6 @@ const ProgressNumber2 = styled(ProgressText)`
color: ${({ theme }) => `${theme.color.gray500}`};
`;

const ProgressBarWrapper = styled.div`
align-self: stretch;
position: relative;
`;
const ProgressContainer = styled.div`
align-self: stretch;
height: 45px;
flex-direction: column;
justify-content: flex-start;
align-items: center;
gap: 8px;
display: flex;
`;

export const DesignTextView1 = () => {
const currentStep = 1;
const totalSteps = 5;
@@ -90,20 +83,16 @@ export const DesignTextView1 = () => {
<>
<TextContainer>
<InnerContainer>
<ProgressContainer>
<ProgressWrapper>
<ProgressNumber1>{currentStep} </ProgressNumber1>
<ProgressNumber2>/ {totalSteps}</ProgressNumber2>
</ProgressWrapper>
<ProgressBarWrapper>
<ProgressBar $currentStep={currentStep} $totalSteps={totalSteps} />
</ProgressBarWrapper>
</ProgressContainer>
<ProgressWrapper>
<ProgressNumber1>{currentStep} </ProgressNumber1>
<ProgressNumber2>/ {totalSteps}</ProgressNumber2>
</ProgressWrapper>
<ProgressBar $currentStep={currentStep} $totalSteps={totalSteps} />
</InnerContainer>
<KeywordContainer>
<KeywordTitle>나에게 해당되는 키워드는 무엇인가요?</KeywordTitle>
<KeywordTitle>내가 활동하고 싶은 분야는 어디인가요?</KeywordTitle>
<KeywordDescription>
<KeywordCount>5개</KeywordCount>의 키워드를 선택해주세요.
<span className="highlight">최대 3개</span>의 키워드를 선택해주세요.
</KeywordDescription>
</KeywordContainer>
</TextContainer>
@@ -119,20 +108,16 @@ export const DesignTextView2 = () => {
<>
<TextContainer>
<InnerContainer>
<ProgressContainer>
<ProgressWrapper>
<ProgressNumber1>{currentStep} </ProgressNumber1>
<ProgressNumber2>/ {totalSteps}</ProgressNumber2>
</ProgressWrapper>
<ProgressBarWrapper>
<ProgressBar $currentStep={currentStep} $totalSteps={totalSteps} />
</ProgressBarWrapper>
</ProgressContainer>
<ProgressWrapper>
<ProgressNumber1>{currentStep} </ProgressNumber1>
<ProgressNumber2>/ {totalSteps}</ProgressNumber2>
</ProgressWrapper>
<ProgressBar $currentStep={currentStep} $totalSteps={totalSteps} />
</InnerContainer>
<KeywordContainer>
<KeywordTitle>나에게 해당되는 키워드는 무엇인가요?</KeywordTitle>
<KeywordTitle>사람들에게 알리고 싶은 당신의 가장 큰 특징은 무엇인가요?</KeywordTitle>
<KeywordDescription>
<KeywordCount>5개</KeywordCount>의 키워드를 선택해주세요.
<span className="highlight">최대 3개</span>의 키워드를 선택해주세요.
</KeywordDescription>
</KeywordContainer>
</TextContainer>
@@ -148,20 +133,16 @@ export const DesignTextView3 = () => {
<>
<TextContainer>
<InnerContainer>
<ProgressContainer>
<ProgressWrapper>
<ProgressNumber1>{currentStep} </ProgressNumber1>
<ProgressNumber2>/ {totalSteps}</ProgressNumber2>
</ProgressWrapper>
<ProgressBarWrapper>
<ProgressBar $currentStep={currentStep} $totalSteps={totalSteps} />
</ProgressBarWrapper>
</ProgressContainer>
<ProgressWrapper>
<ProgressNumber1>{currentStep} </ProgressNumber1>
<ProgressNumber2>/ {totalSteps}</ProgressNumber2>
</ProgressWrapper>
<ProgressBar $currentStep={currentStep} $totalSteps={totalSteps} />
</InnerContainer>
<KeywordContainer>
<KeywordTitle>나에게 해당되는 키워드는 무엇인가요?</KeywordTitle>
<KeywordTitle>내가 생각하는 나의 능력은 무엇인가요?</KeywordTitle>
<KeywordDescription>
<KeywordCount>5개</KeywordCount>의 키워드를 선택해주세요.
<span className="highlight">최대 5개</span>의 키워드를 선택하거나 입력해주세요.
</KeywordDescription>
</KeywordContainer>
</TextContainer>
@@ -177,20 +158,16 @@ export const DesignTextView4 = () => {
<>
<TextContainer>
<InnerContainer>
<ProgressContainer>
<ProgressWrapper>
<ProgressNumber1>{currentStep} </ProgressNumber1>
<ProgressNumber2>/ {totalSteps}</ProgressNumber2>
</ProgressWrapper>
<ProgressBarWrapper>
<ProgressBar $currentStep={currentStep} $totalSteps={totalSteps} />
</ProgressBarWrapper>
</ProgressContainer>
<ProgressWrapper>
<ProgressNumber1>{currentStep} </ProgressNumber1>
<ProgressNumber2>/ {totalSteps}</ProgressNumber2>
</ProgressWrapper>
<ProgressBar $currentStep={currentStep} $totalSteps={totalSteps} />
</InnerContainer>
<KeywordContainer>
<KeywordTitle>나에게 해당되는 키워드는 무엇인가요?</KeywordTitle>
<KeywordTitle>어떤 경로로 나를 알리고 싶나요?</KeywordTitle>
<KeywordDescription>
<KeywordCount>5개</KeywordCount>키워드를 선택해주세요.
<span className="highlight">최대 2개</span>플랫폼을 선택해주세요.
</KeywordDescription>
</KeywordContainer>
</TextContainer>
@@ -206,20 +183,16 @@ export const DesignTextView5 = () => {
<>
<TextContainer>
<InnerContainer>
<ProgressContainer>
<ProgressWrapper>
<ProgressNumber1>{currentStep} </ProgressNumber1>
<ProgressNumber2>/ {totalSteps}</ProgressNumber2>
</ProgressWrapper>
<ProgressBarWrapper>
<ProgressBar $currentStep={currentStep} $totalSteps={totalSteps} />
</ProgressBarWrapper>
</ProgressContainer>
<ProgressWrapper>
<ProgressNumber1>{currentStep} </ProgressNumber1>
<ProgressNumber2>/ {totalSteps}</ProgressNumber2>
</ProgressWrapper>
<ProgressBar $currentStep={currentStep} $totalSteps={totalSteps} />
</InnerContainer>
<KeywordContainer>
<KeywordTitle>나에게 해당되는 키워드는 무엇인가요?</KeywordTitle>
<KeywordTitle>나를 어떤 커리어로 정의하고 싶나요?</KeywordTitle>
<KeywordDescription>
<KeywordCount>5개</KeywordCount>의 키워드를 선택해주세요.
<span className="highlight">1개</span>의 키워드를 선택하거나 입력해주세요.
</KeywordDescription>
</KeywordContainer>
</TextContainer>
74 changes: 74 additions & 0 deletions src/components/common/Chip/InputChip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { useState } from 'react';

import styled from 'styled-components';

import { ReactComponent as AddIcon } from '@/assets/icons/add.svg';

interface InputChipProps {
onAdd: (chip: string) => void;
}

const InputChipContainer = styled.div`
width: 102px;
height: 34px;
padding: 7px 12px;
background: ${({ theme }) => `${theme.color.gray100}`};
border-radius: 8px;
border: 1px ${({ theme }) => `${theme.color.gray250}`} solid;
display: inline-flex;
align-items: center;
gap: 6px;
`;

const InputField = styled.input`
${({ theme }) => theme.font.desktop.label1m};
color: ${({ theme }) => `${theme.color.gray500}`};
background-color: transparent;
border: none;
outline: none;
min-width: 50px;
flex-grow: 1;
&::placeholder {
background-color: transparent;
}
`;

const IconContainer = styled.div<{ $showIcon: boolean }>`
width: 16px;
height: 16px;
display: ${(props) => (props.$showIcon ? 'flex' : 'none')};
`;

const InputChip = ({ onAdd }: InputChipProps) => {
const [inputValue, setInputValue] = useState('');

const handleAdd = () => {
if (inputValue.trim()) {
onAdd(inputValue.trim());
setInputValue('');
}
};

const handleKeyPress = (e: { key: string }) => {
if (e.key === 'Enter') {
handleAdd();
}
};

return (
<InputChipContainer>
<IconContainer $showIcon={!inputValue}>
<AddIcon />
</IconContainer>
<InputField
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
onKeyDown={handleKeyPress}
placeholder="추가하기"
/>
</InputChipContainer>
);
};

export default InputChip;
71 changes: 71 additions & 0 deletions src/components/common/Chip/PlatformChip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { styled } from 'styled-components';

interface PlatformProps {
state: number;
}

interface PlatformChipProps {
chipIcon: React.ReactNode;
state: number;
index: number;
onToggle: (index: number) => void;
text: string;
}

export const PlatformChip = ({ chipIcon, state, index, onToggle, text }: PlatformChipProps) => {
return (
<StyledContainer state={state} onClick={() => onToggle(index)}>
<ImageContainer>
<IconContainer>{chipIcon}</IconContainer>
</ImageContainer>
<TextContainer state={state}>{text}</TextContainer>
</StyledContainer>
);
};

const StyledContainer = styled.div<PlatformProps>`
width: 104px;
height: 137px;
border-radius: 8px;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 16px;
display: inline-flex;
cursor: pointer;
border: 2px solid
${(props) => (props.state === 1 ? props.theme.color.gray200 : props.theme.color.primary600)};
background-color: ${(props) =>
props.state === 1 ? props.theme.color.white : props.theme.color.primary500};
color: ${(props) => (props.state === 1 ? props.theme.color.gray400 : props.theme.color.white)};
&:hover {
border: 2px solid
${(props) =>
props.state === 1 ? props.theme.color.primary200 : props.theme.color.primary600};
background: ${(props) =>
props.state === 1 ? props.theme.color.primary50 : props.theme.color.primary500};
color: ${(props) =>
props.state === 1 ? props.theme.color.primary700 : props.theme.color.primary50};
}
`;

const IconContainer = styled.div`
width: 40px;
height: 40px;
position: absolute;
border-radius: 8px;
`;

const ImageContainer = styled.div`
width: 40px;
height: 40px;
position: relative;
`;

const TextContainer = styled.div<PlatformProps>`
text-align: center;
${({ theme }) => theme.font.desktop.label1m};
word-wrap: break-word;
`;
12 changes: 12 additions & 0 deletions src/components/common/Layout/DefineLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Outlet } from 'react-router-dom';

import DefineHeaderNavigation from '@/components/common/Navigation/DefineHeaderNavigation';

export const DefineLayout = () => {
return (
<>
<DefineHeaderNavigation />
<Outlet />
</>
);
};
12 changes: 12 additions & 0 deletions src/components/common/Layout/DesignLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Outlet } from 'react-router-dom';

import DesignHeaderNavigation from '@/components/common/Navigation/DesignHeaderNavigation';

export const DesignLayout = () => {
return (
<>
<DesignHeaderNavigation />
<Outlet />
</>
);
};
12 changes: 0 additions & 12 deletions src/components/common/Layout/TestLayout.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -70,7 +70,7 @@ const StyledButton = styled.button`
}
`;

const TestNavigation = () => {
const DefineHeaderNavigation = () => {
//const navigate = useNavigate();

const handleButtonClick = () => {
@@ -87,4 +87,4 @@ const TestNavigation = () => {
);
};

export default TestNavigation;
export default DefineHeaderNavigation;
90 changes: 90 additions & 0 deletions src/components/common/Navigation/DesignHeaderNavigation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/* import { useNavigate } from 'react-router-dom'; */
import styled from 'styled-components';

const StyledContainer = styled.header`
display: flex;
justify-content: space-between;
align-items: center;
position: fixed;
top: 0;
left: 0;
z-index: 10;
width: 100%;
height: 76px;
padding: 0 64px;
background: ${({ theme }) => theme.color.white};
@media ${({ theme }) => theme.device.tablet} {
padding: 0 20px;
}
@media ${({ theme }) => theme.device.mobile} {
padding: 0 20px;
}
`;

const Container = styled.div`
width: 100%;
height: 100%;
background: transparent;
display: flex;
justify-content: space-between;
align-items: center;
`;

const Title = styled.div`
color: ${({ theme }) => theme.color.gray700};
${({ theme }) => theme.font.desktop.body1b};
@media ${({ theme }) => theme.device.tablet} {
${({ theme }) => theme.font.mobile.body1b};
}
@media ${({ theme }) => theme.device.mobile} {
${({ theme }) => theme.font.mobile.body1b};
}
word-wrap: break-word;
`;

const StyledButton = styled.button`
padding: 8px 24px;
background-color: ${({ theme }) => theme.color.primary50};
border-radius: 8px;
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
color: ${({ theme }) => theme.color.primary700};
${({ theme }) => theme.font.desktop.label1m};
@media ${({ theme }) => theme.device.tablet} {
${({ theme }) => theme.font.mobile.body1b};
}
@media ${({ theme }) => theme.device.mobile} {
${({ theme }) => theme.font.mobile.body1b};
}
`;

const DesignHeaderNavigation = () => {
//const navigate = useNavigate();

const handleButtonClick = () => {
// TODO: 홈페이지로 이동하도록 변경하기
window.location.href = 'https://selpiece.framer.website';
};
return (
<StyledContainer>
<Container>
<Title>Design 설계하기</Title>
<StyledButton onClick={handleButtonClick}>종료하기</StyledButton>
</Container>
</StyledContainer>
);
};

export default DesignHeaderNavigation;
90 changes: 90 additions & 0 deletions src/components/common/Navigation/DiscoverHeaderNavigation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/* import { useNavigate } from 'react-router-dom'; */
import styled from 'styled-components';

const StyledContainer = styled.header`
display: flex;
justify-content: space-between;
align-items: center;
position: fixed;
top: 0;
left: 0;
z-index: 10;
width: 100%;
height: 76px;
padding: 0 64px;
background: ${({ theme }) => theme.color.white};
@media ${({ theme }) => theme.device.tablet} {
padding: 0 20px;
}
@media ${({ theme }) => theme.device.mobile} {
padding: 0 20px;
}
`;

const Container = styled.div`
width: 100%;
height: 100%;
background: transparent;
display: flex;
justify-content: space-between;
align-items: center;
`;

const Title = styled.div`
color: ${({ theme }) => theme.color.gray700};
${({ theme }) => theme.font.desktop.body1b};
@media ${({ theme }) => theme.device.tablet} {
${({ theme }) => theme.font.mobile.body1b};
}
@media ${({ theme }) => theme.device.mobile} {
${({ theme }) => theme.font.mobile.body1b};
}
word-wrap: break-word;
`;

const StyledButton = styled.button`
padding: 8px 24px;
background-color: ${({ theme }) => theme.color.primary50};
border-radius: 8px;
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
color: ${({ theme }) => theme.color.primary700};
${({ theme }) => theme.font.desktop.label1m};
@media ${({ theme }) => theme.device.tablet} {
${({ theme }) => theme.font.mobile.body1b};
}
@media ${({ theme }) => theme.device.mobile} {
${({ theme }) => theme.font.mobile.body1b};
}
`;

const DiscoverHeaderNavigation = () => {
//const navigate = useNavigate();

const handleButtonClick = () => {
// TODO: 홈페이지로 이동하도록 변경하기
window.location.href = 'https://selpiece.framer.website';
};
return (
<StyledContainer>
<Container>
<Title>Discover 이해하기</Title>
<StyledButton onClick={handleButtonClick}>종료하기</StyledButton>
</Container>
</StyledContainer>
);
};

export default DiscoverHeaderNavigation;
73 changes: 73 additions & 0 deletions src/constants/designChip.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
export const CHIP_DATA1 = [
'드로잉',
'공예',
'요리',
'음악',
'운동',
'라이프스타일',
'사진/영상',
'금융/제테크',
'창업/부업',
'프로그래밍',
'데이터사이언스',
'AI',
'제2외국어',
'뷰티',
'테크/디지털',
'심리/상담',
'여행',
'자기계발',
'기타',
];

export const CHIP_DATA2 = [
'트렌드세터의',
'성장지향적인',
'적응력 높은',
'미니멀리스트의',
'맥시멀리스트의',
'건강한',
'열광적인',
'도전적인',
'혁신적인',
'개성있는',
'협력적인',
'창의적인',
'사교적인',
'목표지향적인',
'예술적인',
];

export const CHIP_DATA3 = [
'목표달성',
'의사소통',
'문서화',
'문제해결',
'팀워크',
'목표달성능력',
'실행력',
'리더십',
'분석력',
'전략',
'책임감',
'도전정신',
'창의력',
'회복탄력성',
'설득력',
'그로스 마인드셋',
];
export const CHIP_DATA4 = ['Youtube', 'Instagram', 'LinkedIn', 'Pinterest', 'Medium', 'Naver Blog'];

export const CHIP_DATA5 = [
'마케터',
'CEO',
'기획자',
'디자이너',
'개발자',
'프리랜서',
'강연자',
'학생',
'교수',
'유튜버',
'인플루언서',
];
32 changes: 18 additions & 14 deletions src/routers/router.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import { Navigate, Route, Routes } from 'react-router-dom';

/* import { MainLayout } from '@/components/common/Layout/MainLayout'; */
import { TestLayout } from '@/components/common/Layout/TestLayout';
import { DefineLayout } from '@/components/common/Layout/DefineLayout';
import { DesignLayout } from '@/components/common/Layout/DesignLayout';
import { DefineResultPage } from '@/pages/DefineResultPage';
import { DefineStartPage } from '@/pages/DefineStartPage';
import { DefineTestPage1, DefineTestPage2, DefineTestPage3 } from '@/pages/DefineTestPage';
/* import {
import {
DesignTestPage1,
DesignTestPage2,
DesignTestPage3,
DesignTestPage4,
DesignTestPage5,
} from '@/pages/DesignTestPage';
} from '@/pages/DesignTestPage'; /*
import { HomePage } from '@/pages/HomePage';
import { LoginPage } from '@/pages/LoginPage';
import { OnboardingPage } from '@/pages/OnboardingPage';
import { RedirectPage } from '@/pages/RedirectPage';
import { OnboardingPage } from '@/pages/OnboardingPage';*/
import { RedirectPage } from '@/pages/RedirectPage'; /*
import { SelfUnderstandPage } from '@/pages/SelfUnderstandPage';
import { ExceptPreMemberRoute } from '@/routers/ExceptPreMemberRoute'; */

@@ -33,24 +34,27 @@ export const Router = () => {
//</Route>
</Route>
</Route> */}
<Route path="test" element={<TestLayout />}>
<Route path="define">
<Route path="test">
<Route path="define" element={<DefineLayout />}>
<Route index element={<Navigate to="1" replace />}></Route>
<Route path="1" element={<DefineStartPage />} />
<Route path="2" element={<DefineTestPage1 />} />
<Route path="3" element={<DefineTestPage2 />} />
<Route path="4" element={<DefineTestPage3 />} />
<Route path=":defineId" element={<DefineResultPage />} />
</Route>
{/* <Route path="design/1" element={<DesignTestPage1 />} />
<Route path="design/2" element={<DesignTestPage2 />} />
<Route path="design/3" element={<DesignTestPage3 />} />
<Route path="design/4" element={<DesignTestPage4 />} />
<Route path="design/5" element={<DesignTestPage5 />} /> */}
<Route path="design" element={<DesignLayout />}>
<Route index element={<Navigate to="1" replace />}></Route>
<Route path="1" element={<DesignTestPage1 />} />
<Route path="2" element={<DesignTestPage2 />} />
<Route path="3" element={<DesignTestPage3 />} />
<Route path="4" element={<DesignTestPage4 />} />
<Route path="5" element={<DesignTestPage5 />} />
</Route>
</Route>
{/* <Route path="/login" element={<RedirectPage />} />
<Route path="/login" element={<RedirectPage />} />
<Route path="/tt" element={<DefineResultPage />} />
<Route path="*" element={<Navigate to="/" replace />} /> */}
<Route path="*" element={<Navigate to="/" replace />} />
<Route path="*" element={<Navigate to="/test/define" replace />} />
</Routes>
);