From d36ec5d739487bccb39e334ce64bd243bd310585 Mon Sep 17 00:00:00 2001 From: ooooorobo Date: Sat, 13 Nov 2021 17:03:09 +0900 Subject: [PATCH 01/31] feat: add icons --- src/components/icon/ColoredCopy.icon.tsx | 33 ++++++++++++++++++++++++ src/components/icon/ColoredPin.icon.tsx | 19 ++++++++++++++ src/components/icon/Star.icon.tsx | 18 +++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 src/components/icon/ColoredCopy.icon.tsx create mode 100644 src/components/icon/ColoredPin.icon.tsx create mode 100644 src/components/icon/Star.icon.tsx diff --git a/src/components/icon/ColoredCopy.icon.tsx b/src/components/icon/ColoredCopy.icon.tsx new file mode 100644 index 0000000..a314ffb --- /dev/null +++ b/src/components/icon/ColoredCopy.icon.tsx @@ -0,0 +1,33 @@ +function ColoredCopyIcon() { + return ( + + + + + + + + ); +} + +export default ColoredCopyIcon; diff --git a/src/components/icon/ColoredPin.icon.tsx b/src/components/icon/ColoredPin.icon.tsx new file mode 100644 index 0000000..3768091 --- /dev/null +++ b/src/components/icon/ColoredPin.icon.tsx @@ -0,0 +1,19 @@ +function ColoredPinIcon() { + return ( + + + + + ); +} + +export default ColoredPinIcon; diff --git a/src/components/icon/Star.icon.tsx b/src/components/icon/Star.icon.tsx new file mode 100644 index 0000000..4895333 --- /dev/null +++ b/src/components/icon/Star.icon.tsx @@ -0,0 +1,18 @@ +function StarIcon() { + return ( + + + + ); +} + +export default StarIcon; From 308e74649132cf5efb40f391dbb3d6e78668b211 Mon Sep 17 00:00:00 2001 From: ooooorobo Date: Sat, 13 Nov 2021 17:03:58 +0900 Subject: [PATCH 02/31] fix: remove and separate study list element --- .../molecules/StudyInfo.component.tsx | 102 ++++++++++++ .../molecules/StudyListElement.component.tsx | 153 ------------------ .../organs/StudyListElement.component.tsx | 72 +++++++++ .../StudyListElement.stories.tsx | 4 +- src/templates/UserMain.template.tsx | 2 +- 5 files changed, 177 insertions(+), 156 deletions(-) create mode 100644 src/components/molecules/StudyInfo.component.tsx delete mode 100644 src/components/molecules/StudyListElement.component.tsx create mode 100644 src/components/organs/StudyListElement.component.tsx rename src/stories/{molcules => organs}/StudyListElement.stories.tsx (82%) diff --git a/src/components/molecules/StudyInfo.component.tsx b/src/components/molecules/StudyInfo.component.tsx new file mode 100644 index 0000000..c379da2 --- /dev/null +++ b/src/components/molecules/StudyInfo.component.tsx @@ -0,0 +1,102 @@ +import PersonIcon from "@src/components/icon/Person.icon"; +import ColoredCalendarIcon from "@src/components/icon/ColoredCalendar.icon"; +import styled from "styled-components"; +import theme, { FontSize } from "@src/styles/theme"; +import { useMemo } from "react"; +import { dateToFormatted } from "@src/utils/dayjs.util"; + +const InfoWrapper = styled.div` + display: flex; + margin-bottom: 10px; + font-size: ${FontSize.Small}; +`; +const IconPrefixWrapper = styled.span` + display: flex; + align-items: center; + margin-right: 15px; + svg { + margin-right: 5px; + } +`; +const CategoryWrapper = styled.div` + display: flex; + align-items: center; + font-size: ${FontSize.Small}; + &:not(:last-child) { + margin-bottom: 10px; + } +`; +const Category = styled.span` + font-size: ${FontSize.Small}; + padding-top: 2px; + + &:not(:last-child) { + ::after { + content: ","; + margin-right: 4px; + } + } +`; +const CategoryTypeTag = styled.span` + background-color: ${theme.color.point}; + color: #fff; + font-weight: 700; + font-size: ${FontSize.Small}; + text-align: center; + padding-top: 2px; + width: 40px; + height: 20px; + border-radius: 20px; + margin-right: 7px; +`; + +const S = { + InfoWrapper, + IconPrefixWrapper, + CategoryWrapper, + CategoryTypeTag, + Category, +}; +function StudyInfoComponent({ study }) { + const date = useMemo( + () => + study.startDate && study.endDate + ? `${dateToFormatted(study.startDate)} - ${dateToFormatted( + study.endDate, + )}` + : "협의 후 결정", + [study], + ); + const people = useMemo(() => `${study.peopleCnt || 1}명`, [study]); + + return ( +
+ + + + {people} + + + + {date} + + + + GIVE + {study.give.length === 0 ? "아직 없어요" : ""} + {study.give.map((x) => ( + {x} + ))} + + + TAKE + {study.take.length === 0 ? "다 좋아요!" : ""} + {study.take.map((x) => ( + {x} + ))} + +
+ ); +} + +export default StudyInfoComponent; diff --git a/src/components/molecules/StudyListElement.component.tsx b/src/components/molecules/StudyListElement.component.tsx deleted file mode 100644 index 34ebec1..0000000 --- a/src/components/molecules/StudyListElement.component.tsx +++ /dev/null @@ -1,153 +0,0 @@ -import { useMemo } from "react"; -import styled from "styled-components"; - -// components -import { StudyListElement } from "@src/models/dto/study.dto"; -import PersonIcon from "@src/components/icon/Person.icon"; -import ColoredCalendarIcon from "@src/components/icon/ColoredCalendar.icon"; - -// utils -import { dateToFormatted } from "@src/utils/dayjs.util"; - -// styles -import theme, { FontSize, Padding } from "@src/styles/theme"; -import Image from "@src/components/atoms/Image"; - -export interface StudyListElementComponentProps { - study: StudyListElement; -} - -const Container = styled.div` - display: grid; - grid-template-columns: auto 100px; - width: 100%; - cursor: pointer; - user-select: none; - padding: ${Padding.pageX}; -`; -const ContentsWrapper = styled.div` - width: 100%; - - h3 { - font-weight: 700; - font-size: ${FontSize.PrimaryDescription}; - margin-bottom: 5px; - } -`; -const InfoWrapper = styled.div` - display: flex; - margin-bottom: 10px; - font-size: ${FontSize.Small}; -`; -const IconPrefixWrapper = styled.span` - display: flex; - align-items: center; - margin-right: 15px; - svg { - margin-right: 5px; - } -`; -const CategoryWrapper = styled.div` - display: flex; - align-items: center; - font-size: ${FontSize.Small}; - &:not(:last-child) { - margin-bottom: 10px; - } -`; -const Category = styled.span` - font-size: ${FontSize.Small}; - padding-top: 2px; - - &:not(:last-child) { - ::after { - content: ","; - margin-right: 4px; - } - } -`; -const CategoryTypeTag = styled.span` - background-color: ${theme.color.point}; - color: #fff; - font-weight: 700; - font-size: ${FontSize.Small}; - text-align: center; - padding-top: 2px; - width: 40px; - height: 20px; - border-radius: 20px; - margin-right: 7px; -`; -const ImageWrapper = styled.div` - width: 100px; - height: 100px; - overflow: hidden; - - border-radius: 6px; - - display: flex; - justify-content: center; - align-items: center; - - img { - width: auto; - } -`; -const S = { - Container, - ContentsWrapper, - InfoWrapper, - IconPrefixWrapper, - CategoryWrapper, - CategoryTypeTag, - Category, - ImageWrapper, -}; -function StudyListElementComponent({ study }: StudyListElementComponentProps) { - const date = useMemo( - () => - study.startDate && study.endDate - ? `${dateToFormatted(study.startDate)} - ${dateToFormatted( - study.endDate, - )}` - : "협의 후 결정", - [study], - ); - const people = useMemo(() => `${study.peopleCnt || 1}명`, [study]); - return ( - - -

{study.title}

- - - - {people} - - - - {date} - - - - GIVE - {study.give.length === 0 ? "아직 없어요" : ""} - {study.give.map((x) => ( - {x} - ))} - - - TAKE - {study.take.length === 0 ? "다 좋아요!" : ""} - {study.take.map((x) => ( - {x} - ))} - -
- - {study.title} - -
- ); -} - -export default StudyListElementComponent; diff --git a/src/components/organs/StudyListElement.component.tsx b/src/components/organs/StudyListElement.component.tsx new file mode 100644 index 0000000..c210b57 --- /dev/null +++ b/src/components/organs/StudyListElement.component.tsx @@ -0,0 +1,72 @@ +import { useMemo } from "react"; +import styled from "styled-components"; + +// components +import { StudyListElement } from "@src/models/dto/study.dto"; +import StudyInfoComponent from "@src/components/molecules/StudyInfo.component"; + +// utils +import { dateToFormatted } from "@src/utils/dayjs.util"; + +// styles +import { FontSize, Padding } from "@src/styles/theme"; +import Image from "@src/components/atoms/Image"; + +export interface StudyListElementComponentProps { + study: StudyListElement; +} + +const Container = styled.div` + display: grid; + grid-template-columns: auto 100px; + width: 100%; + cursor: pointer; + user-select: none; + padding: ${Padding.pageX}; +`; +const ContentsWrapper = styled.div` + width: 100%; + + h3 { + font-weight: 700; + font-size: ${FontSize.PrimaryDescription}; + margin-bottom: 5px; + } +`; + +const ImageWrapper = styled.div` + width: 100px; + height: 100px; + overflow: hidden; + + border-radius: 6px; + + display: flex; + justify-content: center; + align-items: center; + + img { + width: auto; + } +`; +const S = { + Container, + ContentsWrapper, + + ImageWrapper, +}; +function StudyListElementComponent({ study }: StudyListElementComponentProps) { + return ( + + +

{study.title}

+ +
+ + {study.title} + +
+ ); +} + +export default StudyListElementComponent; diff --git a/src/stories/molcules/StudyListElement.stories.tsx b/src/stories/organs/StudyListElement.stories.tsx similarity index 82% rename from src/stories/molcules/StudyListElement.stories.tsx rename to src/stories/organs/StudyListElement.stories.tsx index 47e186c..9786233 100644 --- a/src/stories/molcules/StudyListElement.stories.tsx +++ b/src/stories/organs/StudyListElement.stories.tsx @@ -1,8 +1,8 @@ -import StudyListElementComponent from "@src/components/molecules/StudyListElement.component"; +import StudyListElementComponent from "@src/components/organs/StudyListElement.component"; import { StudyListElement as StudyListElementDto } from "@src/models/dto/study.dto"; export default { - title: "molecules/Study List Element", + title: "organs/Study List Element", component: StudyListElementComponent, }; diff --git a/src/templates/UserMain.template.tsx b/src/templates/UserMain.template.tsx index 9fe4f15..bf5e049 100644 --- a/src/templates/UserMain.template.tsx +++ b/src/templates/UserMain.template.tsx @@ -9,7 +9,7 @@ import BottomNavigationComponent from "@src/components/organs/BottomNavigation.c import CakeIcon from "@src/components/icon/Cake.icon"; import { TextButton } from "@src/components/atoms/TextButton"; import { BoldDivider, LightDivider } from "@src/components/atoms/Divider"; -import StudyListElementComponent from "@src/components/molecules/StudyListElement.component"; +import StudyListElementComponent from "@src/components/organs/StudyListElement.component"; // styles import theme, { Color, FontSize, Padding } from "@src/styles/theme"; From 6bcbd747c70e953a18d93c5274751c5bfebb5c6d Mon Sep 17 00:00:00 2001 From: ooooorobo Date: Sat, 13 Nov 2021 17:04:06 +0900 Subject: [PATCH 03/31] feat: add new color prop to button --- src/components/atoms/Button.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/atoms/Button.tsx b/src/components/atoms/Button.tsx index 34b84ca..9095b45 100644 --- a/src/components/atoms/Button.tsx +++ b/src/components/atoms/Button.tsx @@ -9,7 +9,7 @@ export interface ButtonStyleProps extends BaseProps { filled?: boolean; width?: string; height?: string; - color?: "gray" | "primary" | "white" | string; + color?: "gray" | "primary" | "white" | "point" | string; shape?: "rounded" | "full-rounded"; textAlign?: "left" | "center"; } @@ -53,6 +53,8 @@ export const Button = styled.button` return Color.mainGradient; case "gray": return theme.color.gray2; + case "point": + return theme.color.point; default: return color; } @@ -72,7 +74,9 @@ export const Button = styled.button` }}; color: ${({ color, disabled, filled = true }) => - color === "primary" && !disabled && filled ? "#fff" : theme.color.black}; + (color === "primary" || color === "point") && !disabled && filled + ? "#fff" + : theme.color.black}; width: ${({ width }) => width || "100%"}; `; From 764a308de1000786950e78109aa5697535da67a5 Mon Sep 17 00:00:00 2001 From: ooooorobo Date: Sat, 13 Nov 2021 17:04:28 +0900 Subject: [PATCH 04/31] fix: change profile fram style props --- .../molecules/ProfileFrame.component.tsx | 68 +++++++++++++++---- .../signup/DetailsInputStep.component.tsx | 10 ++- src/models/dto/study.dto.d.ts | 6 ++ 3 files changed, 67 insertions(+), 17 deletions(-) diff --git a/src/components/molecules/ProfileFrame.component.tsx b/src/components/molecules/ProfileFrame.component.tsx index a14434d..163f2a0 100644 --- a/src/components/molecules/ProfileFrame.component.tsx +++ b/src/components/molecules/ProfileFrame.component.tsx @@ -3,25 +3,56 @@ import UploadComponent from "@src/components/molecules/Upload.component"; import styled from "styled-components"; import theme from "@src/styles/theme"; import { BaseProps, BaseStyleProps } from "@src/styles/common"; +import { Resource } from "@src/models/dto/api-response"; + +interface ProfileFrameProps { + mb?: string; + size?: "large" | "small"; + allowUpload?: boolean; + imgSrc?: string; + onUploadImage?: (e: Resource) => void; +} const ProfileImageWrapper = styled.div` - ${BaseStyleProps} + ${BaseStyleProps}; position: relative; width: fit-content; - margin-left: auto; - margin-right: auto; `; -const CircleImageFrame = styled.div` - width: 80px; - height: 80px; - border-radius: 50%; +const CircleImageFrame = styled.div` + border: 6px solid ${theme.color.primary}; img { width: auto; - height: 80px; + height: ${({ size }) => (size === "large" ? "80px" : "32px")}; + } + + svg { + width: auto; + height: ${({ size }) => (size === "large" ? "48px" : "18px")}; } + ${({ size }) => { + switch (size) { + case "large": + return ` + width: 80px; + height: 80px; + `; + case "small": + return ` + width: 32px; + height: 32px; + border-width: 3px; + `; + default: + return ` + width: 80px; + height: 80px;`; + } + }} + border-radius: 50%; + display: flex; justify-content: center; align-items: center; @@ -30,8 +61,6 @@ const CircleImageFrame = styled.div` position: relative; background-color: ${theme.color.gray0}; - - border: 6px solid ${theme.color.primary}; `; const S = { @@ -39,15 +68,24 @@ const S = { CircleImageFrame, }; +ProfileFrameComponent.defaultProps = { + mb: "", + size: "large", + allowUpload: true, + imgSrc: "", + onUploadImage: null, +}; + function ProfileFrameComponent({ mb = "", - allowUpload, - imgSrc, - onUploadImage, -}) { + size = "large", + allowUpload = true, + imgSrc = "", + onUploadImage = null, +}: ProfileFrameProps) { return ( - + {imgSrc ? 프로필 이미지 : } {allowUpload && } diff --git a/src/components/organs/signup/DetailsInputStep.component.tsx b/src/components/organs/signup/DetailsInputStep.component.tsx index 75d1edf..06d6e70 100644 --- a/src/components/organs/signup/DetailsInputStep.component.tsx +++ b/src/components/organs/signup/DetailsInputStep.component.tsx @@ -14,11 +14,17 @@ import SelectComponent from "@src/components/atoms/Select"; import ProfileFrameComponent from "@src/components/molecules/ProfileFrame.component"; import { ErrorMessage } from "@src/components/atoms/text/ErrorMessage"; import { BaseProps, BaseStyleProps } from "@src/styles/common"; +import { Resource } from "@src/models/dto/api-response"; const Container = styled.div``; const FormWrapper = styled.div` - ${BaseStyleProps} + ${BaseStyleProps}; + + div { + margin-left: auto; + margin-right: auto; + } text-align: center; margin-top: 10px; @@ -46,7 +52,7 @@ const DetailsInputStepComponent = observer(() => { const [nickname, setNickname] = useState(""); const onUploadImage = useCallback( - (uploaded) => { + (uploaded: Resource) => { signupStore.setFormValue("img", uploaded.path); }, [signupStore], diff --git a/src/models/dto/study.dto.d.ts b/src/models/dto/study.dto.d.ts index e8097ab..a3ba30d 100644 --- a/src/models/dto/study.dto.d.ts +++ b/src/models/dto/study.dto.d.ts @@ -26,4 +26,10 @@ export interface StudyListElement { img: string; } +export interface StudyDetailDto extends StudyListElement { + contents: string; + location: string; + createdAt: string; +} + export default {}; From d93377a89aa236c9ddab4c267ec62222dce780f2 Mon Sep 17 00:00:00 2001 From: ooooorobo Date: Sat, 13 Nov 2021 17:04:38 +0900 Subject: [PATCH 05/31] feat: add study detail template ui --- .../templates/StudyDetailTemplate.stories.tsx | 26 ++++ src/templates/StudyDetail.template.tsx | 143 ++++++++++++++++++ src/utils/dayjs.util.ts | 4 +- 3 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 src/stories/templates/StudyDetailTemplate.stories.tsx create mode 100644 src/templates/StudyDetail.template.tsx diff --git a/src/stories/templates/StudyDetailTemplate.stories.tsx b/src/stories/templates/StudyDetailTemplate.stories.tsx new file mode 100644 index 0000000..5b72b4d --- /dev/null +++ b/src/stories/templates/StudyDetailTemplate.stories.tsx @@ -0,0 +1,26 @@ +import StudyDetailTemplate from "@src/templates/StudyDetail.template"; +import { StudyDetailDto } from "@src/models/dto/study.dto"; + +export default { + title: "template/Study Detail", + component: StudyDetailTemplate, +}; + +const studySample: StudyDetailDto = { + id: 1, + title: "애프터 이펙트 알려주실 분 구합니다.", + contents: + "저는 영상을 배우고 싶은데 혹시 영상러들 중 일러스트 관심잇으신 분 계신가요?", + location: "아주대학교 카탈로그", + peopleCnt: 1, + startDate: "2021-11-07T00:00:00.000+00:00", + endDate: "2021-11-09T00:00:00.000+00:00", + createdAt: "2021-07-21T00:00:00.000+00:00", + give: ["요리", "베이킹"], + take: ["운동", "영상 편집"], + img: "https://cdn.pixabay.com/photo/2021/09/01/16/09/cake-6591719__340.jpg", +}; + +const Template = () => ; + +export const StudyDetail = Template.bind({}); diff --git a/src/templates/StudyDetail.template.tsx b/src/templates/StudyDetail.template.tsx new file mode 100644 index 0000000..23da041 --- /dev/null +++ b/src/templates/StudyDetail.template.tsx @@ -0,0 +1,143 @@ +import Image from "@src/components/atoms/Image"; +import ProfileFrameComponent from "@src/components/molecules/ProfileFrame.component"; +import StarIcon from "@src/components/icon/Star.icon"; +import { dateToFormatted } from "@src/utils/dayjs.util"; +import { LightDivider } from "@src/components/atoms/Divider"; +import StudyInfoComponent from "@src/components/molecules/StudyInfo.component"; +import ColoredPinIcon from "@src/components/icon/ColoredPin.icon"; +import ColoredCopyIcon from "@src/components/icon/ColoredCopy.icon"; +import styled from "styled-components"; +import theme, { FontSize, Padding, windowSize } from "@src/styles/theme"; +import { BottomSection } from "@src/components/atoms/BottomSection"; +import { Button } from "@src/components/atoms/Button"; +import TitleHeaderComponent from "@src/components/molecules/TitleHeader.component"; +import { NoScroll } from "@src/styles/common"; + +const Container = styled.div` + padding-top: 60px; + padding-bottom: 80px; + overflow: auto; + height: 100vh; + ${NoScroll}; +`; +const StudyContentsWrapper = styled.div` + padding: 20px ${Padding.pageX} 0; + h3 { + margin-bottom: 2px; + } + p { + margin-bottom: 0; + } +`; + +const ImageWrapper = styled.div` + width: 100%; + overflow: hidden; + display: flex; + justify-content: center; + img { + width: ${windowSize.mobile}; + height: auto; + } +`; + +const ProfileWrapper = styled.div` + display: flex; + gap: 8px; + align-items: center; + margin-bottom: 10px; + span { + display: flex; + align-items: center; + svg { + margin-bottom: 3px; + margin-right: 4px; + } + } +`; + +const LocationWrapper = styled.div` + margin-top: 10px; + display: flex; + align-items: center; + font-size: ${FontSize.Small}; + button { + cursor: pointer; + margin-left: 5px; + background-color: transparent; + outline: none; + border: 0; + display: flex; + align-items: center; + color: ${theme.color.primary}; + width: 70px; + float: right; + } +`; + +const StudyWrapper = styled.div` + white-space: pre-wrap; + margin-top: 20px; +`; + +const SubmitWrapper = styled.div` + position: absolute; + right: 20px; + top: 0; + bottom: 0; + display: flex; + align-items: center; +`; +function StudyDetailTemplate({ study }) { + return ( + + + {/* Thumbnail */} + + {study.title} + + + {/* Profile */} + + + 아주대애기 + + + 4.8 + + + {/* Title */} +
+

{study.title}

+

{dateToFormatted(study.createdAt, "YYYY.MM.DD")} 게시

+
+ + {/* Info */} +
+ + +
+ +
+ {study.location} + +
+
+ {/* Contents */} + {study.contents} +
+ + + + + +
+ ); +} + +export default StudyDetailTemplate; diff --git a/src/utils/dayjs.util.ts b/src/utils/dayjs.util.ts index 0df4c51..c7339c4 100644 --- a/src/utils/dayjs.util.ts +++ b/src/utils/dayjs.util.ts @@ -1,6 +1,6 @@ import dayjs from "dayjs"; export const dateFormat = "YY.MM.DD"; -export function dateToFormatted(date) { - return dayjs(date).format(dateFormat); +export function dateToFormatted(date, format = dateFormat) { + return dayjs(date).format(format); } From 6776bac7b768ce1e8fb18fb6c87f12a80bad5db1 Mon Sep 17 00:00:00 2001 From: ooooorobo Date: Sat, 13 Nov 2021 17:32:24 +0900 Subject: [PATCH 06/31] fix: fix lint errors --- src/components/organs/StudyListElement.component.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/components/organs/StudyListElement.component.tsx b/src/components/organs/StudyListElement.component.tsx index c210b57..a60787a 100644 --- a/src/components/organs/StudyListElement.component.tsx +++ b/src/components/organs/StudyListElement.component.tsx @@ -1,13 +1,9 @@ -import { useMemo } from "react"; import styled from "styled-components"; // components import { StudyListElement } from "@src/models/dto/study.dto"; import StudyInfoComponent from "@src/components/molecules/StudyInfo.component"; -// utils -import { dateToFormatted } from "@src/utils/dayjs.util"; - // styles import { FontSize, Padding } from "@src/styles/theme"; import Image from "@src/components/atoms/Image"; From 7d2c7d49316d7b616997c3ec18fcc0906d6e3bd8 Mon Sep 17 00:00:00 2001 From: ooooorobo Date: Sun, 14 Nov 2021 03:26:13 +0900 Subject: [PATCH 07/31] feat: use common page wrapper to add header & footer --- .../organs/PageWrapper.component.tsx | 36 ++++++++++++ .../templates/StudyJoinForm.stories.tsx | 10 ++++ src/templates/StudyCreate.template.tsx | 52 +++++++---------- src/templates/StudyDetail.template.tsx | 57 ++++++++----------- src/templates/StudyJoinForm.template.tsx | 21 +++++++ 5 files changed, 109 insertions(+), 67 deletions(-) create mode 100644 src/components/organs/PageWrapper.component.tsx create mode 100644 src/stories/templates/StudyJoinForm.stories.tsx create mode 100644 src/templates/StudyJoinForm.template.tsx diff --git a/src/components/organs/PageWrapper.component.tsx b/src/components/organs/PageWrapper.component.tsx new file mode 100644 index 0000000..7b7469f --- /dev/null +++ b/src/components/organs/PageWrapper.component.tsx @@ -0,0 +1,36 @@ +import TitleHeaderComponent from "@src/components/molecules/TitleHeader.component"; +import { BottomSection } from "@src/components/atoms/BottomSection"; +import { Button } from "@src/components/atoms/Button"; +import styled from "styled-components"; +import { NoScroll } from "@src/styles/common"; +import { Padding } from "@src/styles/theme"; + +const Container = styled.div` + padding-top: 60px; + padding-bottom: 80px; + overflow: auto; + height: 100vh; + ${NoScroll}; +`; + +const SubmitWrapper = styled.div` + position: absolute; + right: 20px; + top: 0; + bottom: 0; + display: flex; + align-items: center; +`; +function PageWrapperComponent({ title, backLink, button, children }) { + return ( + + +
{children}
+ + {button} + +
+ ); +} + +export default PageWrapperComponent; diff --git a/src/stories/templates/StudyJoinForm.stories.tsx b/src/stories/templates/StudyJoinForm.stories.tsx new file mode 100644 index 0000000..28fb0d5 --- /dev/null +++ b/src/stories/templates/StudyJoinForm.stories.tsx @@ -0,0 +1,10 @@ +import StudyJoinFormTemplate from "@src/templates/StudyJoinForm.template"; + +export default { + title: "template/Study Join Form", + component: StudyJoinFormTemplate, +}; + +const Template = () => ; + +export const StudyJoinForm = Template.bind({}); diff --git a/src/templates/StudyCreate.template.tsx b/src/templates/StudyCreate.template.tsx index d544269..c16ae17 100644 --- a/src/templates/StudyCreate.template.tsx +++ b/src/templates/StudyCreate.template.tsx @@ -10,23 +10,14 @@ import { Button } from "@src/components/atoms/Button"; import { LightUnderlineInput } from "@src/components/atoms/Input"; import DatePicker from "@src/components/atoms/DatePicker"; import Select from "@src/components/atoms/Select"; -import TitleHeaderComponent from "@src/components/molecules/TitleHeader.component"; import AutocompleteCategoryComponent from "@src/components/molecules/AutocompleteCategory.component"; +import { BoldDivider } from "@src/components/atoms/Divider"; +import PageWrapperComponent from "@src/components/organs/PageWrapper.component"; // styles import theme, { Padding } from "@src/styles/theme"; -import { LightUnderline, NoScroll } from "@src/styles/common"; -import { BottomSection } from "@src/components/atoms/BottomSection"; -import { BoldDivider } from "@src/components/atoms/Divider"; - -const Container = styled.div` - padding-top: 60px; - padding-bottom: 80px; - height: 100vh; - overflow: auto; +import { LightUnderline } from "@src/styles/common"; - ${NoScroll}; -`; const FormWrapper = styled.div` padding: 0 ${Padding.pageX}; input, @@ -70,11 +61,6 @@ const WithPrefixIcon = styled.div` align-items: center; `; -const SubmitWrapper = styled.div` - position: absolute; - right: ${Padding.pageX}; - top: 10px; -`; function StudyCreateTemplate({ onSubmit, values, @@ -90,8 +76,21 @@ function StudyCreateTemplate({ }) { const studyTypeList = useMemo(() => getStudyTypeList(), []); return ( - - + + 게시물 작성 + + } + > - - - - - - + ); } diff --git a/src/templates/StudyDetail.template.tsx b/src/templates/StudyDetail.template.tsx index 23da041..2d1e5a0 100644 --- a/src/templates/StudyDetail.template.tsx +++ b/src/templates/StudyDetail.template.tsx @@ -1,25 +1,22 @@ import Image from "@src/components/atoms/Image"; -import ProfileFrameComponent from "@src/components/molecules/ProfileFrame.component"; -import StarIcon from "@src/components/icon/Star.icon"; +import styled from "styled-components"; + +// lib import { dateToFormatted } from "@src/utils/dayjs.util"; -import { LightDivider } from "@src/components/atoms/Divider"; -import StudyInfoComponent from "@src/components/molecules/StudyInfo.component"; + +// components +import StarIcon from "@src/components/icon/Star.icon"; import ColoredPinIcon from "@src/components/icon/ColoredPin.icon"; import ColoredCopyIcon from "@src/components/icon/ColoredCopy.icon"; -import styled from "styled-components"; -import theme, { FontSize, Padding, windowSize } from "@src/styles/theme"; -import { BottomSection } from "@src/components/atoms/BottomSection"; +import { LightDivider } from "@src/components/atoms/Divider"; import { Button } from "@src/components/atoms/Button"; -import TitleHeaderComponent from "@src/components/molecules/TitleHeader.component"; -import { NoScroll } from "@src/styles/common"; +import ProfileFrameComponent from "@src/components/molecules/ProfileFrame.component"; +import StudyInfoComponent from "@src/components/molecules/StudyInfo.component"; +import PageWrapperComponent from "@src/components/organs/PageWrapper.component"; + +// styles +import theme, { FontSize, Padding, windowSize } from "@src/styles/theme"; -const Container = styled.div` - padding-top: 60px; - padding-bottom: 80px; - overflow: auto; - height: 100vh; - ${NoScroll}; -`; const StudyContentsWrapper = styled.div` padding: 20px ${Padding.pageX} 0; h3 { @@ -80,18 +77,17 @@ const StudyWrapper = styled.div` margin-top: 20px; `; -const SubmitWrapper = styled.div` - position: absolute; - right: 20px; - top: 0; - bottom: 0; - display: flex; - align-items: center; -`; function StudyDetailTemplate({ study }) { return ( - - + + 참여 신청 + + } + > {/* Thumbnail */} {study.title} @@ -129,14 +125,7 @@ function StudyDetailTemplate({ study }) { {/* Contents */} {study.contents} - - - - - - + ); } diff --git a/src/templates/StudyJoinForm.template.tsx b/src/templates/StudyJoinForm.template.tsx new file mode 100644 index 0000000..9a9f1c6 --- /dev/null +++ b/src/templates/StudyJoinForm.template.tsx @@ -0,0 +1,21 @@ +// components +import { Button } from "@src/components/atoms/Button"; +import PageWrapperComponent from "@src/components/organs/PageWrapper.component"; + +function StudyJoinFormTemplate() { + return ( + + 참여 신청 + + } + > + hi + + ); +} + +export default StudyJoinFormTemplate; From 1a9fd44c526b38b3667c21109be4656880e049fb Mon Sep 17 00:00:00 2001 From: ooooorobo Date: Sun, 14 Nov 2021 03:38:41 +0900 Subject: [PATCH 08/31] feat: add study join form ui --- src/components/atoms/Input.tsx | 4 ++ src/components/atoms/Textarea.tsx | 22 ++++++++++ .../organs/PageWrapper.component.tsx | 10 +++-- .../templates/StudyJoinForm.stories.tsx | 18 +++++++- src/templates/StudyCreate.template.tsx | 8 +--- src/templates/StudyJoinForm.template.tsx | 41 +++++++++++++++++-- 6 files changed, 88 insertions(+), 15 deletions(-) create mode 100644 src/components/atoms/Textarea.tsx diff --git a/src/components/atoms/Input.tsx b/src/components/atoms/Input.tsx index 23669e1..6c02dd8 100644 --- a/src/components/atoms/Input.tsx +++ b/src/components/atoms/Input.tsx @@ -47,4 +47,8 @@ export const UnderlineInput = styled.input` export const LightUnderlineInput = styled.input` ${LightUnderline}; ${BaseInput}; + + &:disabled { + background-color: #fff; + } `; diff --git a/src/components/atoms/Textarea.tsx b/src/components/atoms/Textarea.tsx new file mode 100644 index 0000000..f5a06b0 --- /dev/null +++ b/src/components/atoms/Textarea.tsx @@ -0,0 +1,22 @@ +import styled from "styled-components"; +import theme from "@src/styles/theme"; +import { BaseProps, BaseStyleProps } from "@src/styles/common"; + +export const Textarea = styled.textarea` + ${BaseStyleProps}; + width: 100%; + border-radius: 9px; + border: 1px solid ${theme.color.primary}; + padding: 8px; + + &:placeholder-shown { + border: 1px solid ${theme.color.gray3}; + } + + &:focus { + outline: none; + border: 1px solid ${theme.color.primary}; + } +`; + +export default { Textarea }; diff --git a/src/components/organs/PageWrapper.component.tsx b/src/components/organs/PageWrapper.component.tsx index 7b7469f..8c1c064 100644 --- a/src/components/organs/PageWrapper.component.tsx +++ b/src/components/organs/PageWrapper.component.tsx @@ -1,12 +1,14 @@ +import styled from "styled-components"; + +// components import TitleHeaderComponent from "@src/components/molecules/TitleHeader.component"; import { BottomSection } from "@src/components/atoms/BottomSection"; -import { Button } from "@src/components/atoms/Button"; -import styled from "styled-components"; + +// styles import { NoScroll } from "@src/styles/common"; -import { Padding } from "@src/styles/theme"; const Container = styled.div` - padding-top: 60px; + padding-top: 80px; padding-bottom: 80px; overflow: auto; height: 100vh; diff --git a/src/stories/templates/StudyJoinForm.stories.tsx b/src/stories/templates/StudyJoinForm.stories.tsx index 28fb0d5..a49b4b6 100644 --- a/src/stories/templates/StudyJoinForm.stories.tsx +++ b/src/stories/templates/StudyJoinForm.stories.tsx @@ -1,10 +1,26 @@ import StudyJoinFormTemplate from "@src/templates/StudyJoinForm.template"; +import { StudyDetailDto } from "@src/models/dto/study.dto"; export default { title: "template/Study Join Form", component: StudyJoinFormTemplate, }; -const Template = () => ; +const studySample: StudyDetailDto = { + id: 1, + title: "애프터 이펙트 알려주실 분 구합니다.", + contents: + "저는 영상을 배우고 싶은데 혹시 영상러들 중 일러스트 관심잇으신 분 계신가요?", + location: "아주대학교 카탈로그", + peopleCnt: 1, + startDate: "2021-11-07T00:00:00.000+00:00", + endDate: "2021-11-09T00:00:00.000+00:00", + createdAt: "2021-07-21T00:00:00.000+00:00", + give: ["요리", "베이킹"], + take: ["운동", "영상 편집"], + img: "https://cdn.pixabay.com/photo/2021/09/01/16/09/cake-6591719__340.jpg", +}; + +const Template = () => ; export const StudyJoinForm = Template.bind({}); diff --git a/src/templates/StudyCreate.template.tsx b/src/templates/StudyCreate.template.tsx index c16ae17..7d228f0 100644 --- a/src/templates/StudyCreate.template.tsx +++ b/src/templates/StudyCreate.template.tsx @@ -13,6 +13,7 @@ import Select from "@src/components/atoms/Select"; import AutocompleteCategoryComponent from "@src/components/molecules/AutocompleteCategory.component"; import { BoldDivider } from "@src/components/atoms/Divider"; import PageWrapperComponent from "@src/components/organs/PageWrapper.component"; +import { Textarea } from "@src/components/atoms/Textarea"; // styles import theme, { Padding } from "@src/styles/theme"; @@ -42,13 +43,6 @@ const WithUnderline = styled.div` margin-bottom: 5px; `; -const Textarea = styled.textarea` - width: 100%; - border-radius: 9px; - border: 1px solid ${theme.color.gray3}; - padding: 8px; -`; - const MidLine = styled.hr` border: 1px solid ${theme.color.gray3}; border-radius: 0; diff --git a/src/templates/StudyJoinForm.template.tsx b/src/templates/StudyJoinForm.template.tsx index 9a9f1c6..8a92e0a 100644 --- a/src/templates/StudyJoinForm.template.tsx +++ b/src/templates/StudyJoinForm.template.tsx @@ -1,11 +1,33 @@ +import styled from "styled-components"; + // components import { Button } from "@src/components/atoms/Button"; import PageWrapperComponent from "@src/components/organs/PageWrapper.component"; -function StudyJoinFormTemplate() { +// styles +import { FontSize, Padding } from "@src/styles/theme"; +import { LightUnderlineInput } from "@src/components/atoms/Input"; +import { Textarea } from "@src/components/atoms/Textarea"; +import { BaseProps, BaseStyleProps } from "@src/styles/common"; + +const ContentsWrapper = styled.div` + padding: ${Padding.page}; +`; + +const FormWrapper = styled.div` + margin-bottom: 20px; +`; +const Label = styled.p` + margin-bottom: 0; + ${BaseStyleProps}; + font-size: ${FontSize.Default}; + font-weight: 500; + padding-left: 10px; +`; +function StudyJoinFormTemplate({ study }) { return ( @@ -13,7 +35,20 @@ function StudyJoinFormTemplate() { } > - hi + + + + + + + +