Skip to content

Commit

Permalink
Merge pull request #36 from prgrms-web-devcourse-final-project/featur…
Browse files Browse the repository at this point in the history
…e/QFEED-56

[Feat] QFEED-56 질문페이지레이아웃 구현
  • Loading branch information
Sunami97 authored Nov 30, 2024
2 parents 3e1fc84 + 48372df commit fccd0f5
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 3 deletions.
5 changes: 3 additions & 2 deletions src/components/ui/ImageUpload/ImageUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { LuImagePlus, LuImageOff } from 'react-icons/lu';
import theme from '@/styles/theme';

interface ImageUploadProps {
onImageUpload?: (file: File) => void; // 이미지 업로드 이벤트 콜백
onImageUpload?: (file: File | null) => void; // 이미지 업로드 이벤트 콜백
}

export const ImageUpload: React.FC<ImageUploadProps> = ({ onImageUpload }) => {
Expand Down Expand Up @@ -46,6 +46,7 @@ export const ImageUpload: React.FC<ImageUploadProps> = ({ onImageUpload }) => {
if (preview) {
setPreview(null);
setError(null);
onImageUpload?.(null);
}
};

Expand Down Expand Up @@ -88,7 +89,7 @@ const UploadBox = styled.div<{ hasPreview: boolean }>`
display: flex;
justify-content: center;
align-items: center;
width: 23.562rem;
width: 100%;
height: 16.25rem;
border: ${({ hasPreview }) => (hasPreview ? '0.125rem solid' : '0.125rem dashed')} ${theme.colors.primary};
border-radius: 1rem;
Expand Down
2 changes: 1 addition & 1 deletion src/pages/QSpacePost/PostGroupPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const PostGroupPage = () => {
console.log('Create group:', { title, description, imageFile });
};

const handleImageUpload = (file: File) => {
const handleImageUpload = (file: File | null) => {
setImageFile(file);
};

Expand Down
194 changes: 194 additions & 0 deletions src/pages/Question/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
import { useState } from 'react';
import styled from '@emotion/styled';
import { IoLockClosed, IoLockOpen } from "react-icons/io5";
import { ImageUpload } from '@/components/ui/ImageUpload/ImageUpload';
import theme from '@/styles/theme';
import Header from '@/components/common/Header';

const QuestionPage = () => {
const [answer, setAnswer] = useState('');
const [isPrivate, setIsPrivate] = useState(true);
const [uploadedImage, setUploadedImage] = useState<File | null>(null);

const handleImageUpload = (file: File | null) => {
setUploadedImage(file);
};

const handleLockToggle = () => {
setIsPrivate((prev) => !prev);
};

const handleSubmit = () => {
alert(`답변: ${answer}\n공개 여부: ${isPrivate ? '비공개' : '공개'}\n이미지: ${uploadedImage ? uploadedImage.name : '없음'}`);
};

return (
<>
<Header />
<Container>
<TitleContainer>
<Title>오늘의 질문</Title>
<Date>D+32</Date>
</TitleContainer>
<Question>맛집을 고르는 기준은 무엇인가요?</Question>
<ImageUploadContainer>
<ImageUpload onImageUpload={handleImageUpload} />
</ImageUploadContainer>
<AnswerContainer>
<InputLabel>
<LabelText>답변을 입력해주세요.</LabelText>
<LockButton onClick={handleLockToggle} isPrivate={isPrivate}>
{isPrivate ? <IoLockClosed size="1rem" /> : <IoLockOpen size="1rem" />}
</LockButton>
</InputLabel>
<Input
value={answer}
onChange={(e) => setAnswer(e.target.value)}
maxLength={100}
/>
</AnswerContainer>
<CharacterCount>{`${answer.length}/100`}</CharacterCount>
<SubmitButton onClick={handleSubmit}>등록하기</SubmitButton>
</Container>
</>
);
};

const Container = styled.div`
display: flex;
flex-direction: column;
align-items: center;
padding: 1.5rem;
background-color: ${theme.colors.background};
width: 100%;
min-height: calc(100vh - 8.25rem);
margin-bottom: 5.25rem;
`;

const TitleContainer = styled.div`
text-align: center;
margin-bottom: 2.5rem;
`;

const Title = styled.h1`
font-size: 1.125rem;
font-weight: bold;
margin-bottom: 0.125rem;
font-family: ${theme.typography.fontFamily.korean};
color: ${theme.colors.gray[600]};
`;

const Date = styled.p`
font-size: 1rem;
font-family: ${theme.typography.fontFamily.english};
color: ${theme.colors.gray[600]};
`;

const Question = styled.p`
font-family: ${theme.typography.header1.fontFamily.korean};
font-weight: bold;
font-size: 1.25rem;
color: ${theme.colors.primary};
text-align: center;
margin-bottom: 1.875rem;
`;

const ImageUploadContainer = styled.div`
width: 100%;
margin-bottom: 1rem;
`;

const AnswerContainer = styled.div`
width: 100%;
`;

const InputLabel = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.5rem;
`;

const LabelText = styled.span`
font-size: 1rem;
color: ${theme.colors.gray[300]};
`;

const LockButton = styled.button<{ isPrivate: boolean }>`
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
background: transparent;
border: 1px solid ${({ isPrivate }) => (isPrivate ? '#FF480E' : '#00796B')};
color: ${theme.colors.black};
border-radius: 0.875rem;
padding: 0.25rem 0.75rem;
font-size: 0.875rem;
cursor: pointer;
transition: all 0.2s ease-in-out;
&:hover {
scale: 1.05;
}
`;

const Input = styled.textarea`
width: 100%;
height: 7rem;
border: 1px solid ${theme.colors.gray[300]};
padding: 0.875rem;
resize: none;
border-radius: 0.5rem;
font-size: 0.875rem;
outline: none;
font-family: ${theme.typography.fontFamily.korean};
color: ${theme.colors.primary};
&:focus {
border-color: ${theme.colors.primary};
}
&::-webkit-scrollbar {
width: 0.5rem;
}
&::-webkit-scrollbar-thumb {
background-color: ${theme.colors.primary};
border-radius: 0.25rem;
}
&::-webkit-scrollbar-thumb:hover {
background-color: ${theme.colors.gray[500]};
}
&::-webkit-scrollbar-track {
background-color: ${theme.colors.gray[100]};
border-radius: 0.25rem;
}
`;

const CharacterCount = styled.p`
font-size: 0.75rem;
color: ${theme.colors.gray[300]};
margin-bottom: 1rem;
align-self: flex-end;
`;

const SubmitButton = styled.button`
width: 100%;
padding: 0.75rem;
background-color: ${theme.colors.primary};
color: ${theme.colors.white};
border: none;
border-radius: 1rem;
font-size: 1rem;
cursor: pointer;
transition: all 0.2s ease-in-out;
&:hover {
scale: 1.02;
}
`;

export default QuestionPage;
5 changes: 5 additions & 0 deletions src/router/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { createBrowserRouter } from 'react-router-dom';
import { LandingPage } from '@/pages/Landing';
import ChatRoom from '@/pages/ChatRoom';
import QSpaceDetailPage from '@/pages/QSpaceDetail';
import QuestionPage from '@/pages/Question';

const router = createBrowserRouter([
{
Expand Down Expand Up @@ -61,6 +62,10 @@ const router = createBrowserRouter([
path: '/chatroom/:id',
element: <ChatRoom />,
},
{
path: '/question/:category',
element: <QuestionPage />,
},
],
},
]);
Expand Down

0 comments on commit fccd0f5

Please sign in to comment.