Skip to content

Commit

Permalink
Feat: 공연 미리보기 버그 수정, 200원 티켓, 다음 주소 검색 API 적용 (운영 배포) (#149)
Browse files Browse the repository at this point in the history
* fix: 401 에러 관련 수정 (#140)

* fix: 드롭다운 색상 수정

* fix: 인증 관련 오류 수정

* fix: 글로벌 에러바운더리 추가

* chore: 주석 코드 리버트

* fix: 덜컥임 수정, 필드 추가 (#142)

* fix: StrictMode 제거 및 불필요한 의존성 제거

* fix: 덜컥임 없도록 수정

* feat: ShowSalesTicketResponse 하위 필드 추가

* feat: 공연 미리보기 모바일 대응 (#144)

* Feat: 유료티켓 200원 작업 (#146)

* feat: 티켓폼 Description 관련 스타일 수정 및 추가

* feat: 일반 티켓 sub description 추가, 0원 또는 200원 이상인 경우에만 validation 통과 처리

* feat: 다음 주소 검색 API 연동 (#147)

* react-daum-postcode 설치

* feat: 공연장명 추가 및 상태 연동

* fix: 공연 상세 미리보기 링크가 화면 바깥으로 튀어나가서 UI 깨지는 것 수정 (#148)

---------

Co-authored-by: Minsu Kim <[email protected]>
Co-authored-by: Shim MunSeong <[email protected]>
  • Loading branch information
3 people authored Aug 31, 2024
1 parent 6060c77 commit 5f33509
Show file tree
Hide file tree
Showing 11 changed files with 196 additions and 75 deletions.
23 changes: 23 additions & 0 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions apps/admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"lodash.debounce": "^4.0.8",
"qrcode.react": "^3.1.0",
"react": "^18.2.0",
"react-daum-postcode": "^3.1.3",
"react-dom": "^18.2.0",
"react-dropzone": "^14.2.3",
"react-hook-form": "^7.50.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import { ImageFile } from '@boolti/api';
import { CloseIcon, FileUpIcon } from '@boolti/icon';
import { TextField, TimePicker } from '@boolti/ui';
import { Button, TextField, TimePicker, useDialog } from '@boolti/ui';
import { add, format } from 'date-fns';
import { useState } from 'react';
import { useRef, useState } from 'react';
import { useDropzone } from 'react-dropzone';
import { Controller, UseFormReturn } from 'react-hook-form';
import DaumPostcode from 'react-daum-postcode';

import Styled from './ShowInfoFormContent.styles';
import { ShowInfoFormInputs } from './types';
import { useBodyScrollLock } from '~/hooks/useBodyScrollLock';

const MAX_IMAGE_COUNT = 3;

type ShowBasicInfoFormInputs = Omit<ShowInfoFormInputs, 'notice' | 'hostName' | 'hostPhoneNumber'>;

interface ShowBasicInfoFormContentProps {
form: UseFormReturn<ShowInfoFormInputs>;
form: UseFormReturn<ShowInfoFormInputs, unknown, ShowInfoFormInputs>;
imageFiles: ImageFile[];
disabled?: boolean;
onDropImage: (acceptedFiles: File[]) => void;
Expand All @@ -28,7 +30,10 @@ const ShowBasicInfoFormContent = ({
onDropImage,
onDeleteImage,
}: ShowBasicInfoFormContentProps) => {
const { watch, control } = form;
const { open, close, isOpen } = useDialog();
const detailAdressInputRef = useRef<HTMLInputElement>(null);

const { watch, control, setValue } = form;

const { getRootProps, getInputProps } = useDropzone({
accept: {
Expand All @@ -48,6 +53,29 @@ const ShowBasicInfoFormContent = ({
placeDetailAddress: false,
});

const openDaumPostCodeWithDialog: React.MouseEventHandler<HTMLButtonElement> = (e) => {
e.preventDefault();
open({
title: '주소 찾기',
content: (
<DaumPostcode
style={{ maxWidth: 426, height: 470 }}
onComplete={(address) => {
setValue('placeStreetAddress', address.roadAddress);
detailAdressInputRef.current?.focus();
}}
onClose={() => {
setHasBlurred((prev) => ({ ...prev, placeStreetAddress: true }));
close();
}}
/>
),
onClose: close,
});
};

useBodyScrollLock(isOpen);

return (
<Styled.ShowInfoFormGroup>
<Styled.ShowInfoFormTitle>기본 정보</Styled.ShowInfoFormTitle>
Expand Down Expand Up @@ -220,14 +248,14 @@ const ShowBasicInfoFormContent = ({
</Styled.ShowInfoFormRow>
<Styled.ShowInfoFormRow>
<Styled.ShowInfoFormContent>
<Styled.ShowInfoFormLabel required>공연 장소</Styled.ShowInfoFormLabel>
<Styled.ShowInfoFormLabel required>공연장명</Styled.ShowInfoFormLabel>
<Styled.TextField>
<Controller
control={control}
rules={{
required: true,
}}
render={({ field: { onChange, onBlur, value } }) => (
render={({ field: { value, onChange, onBlur } }) => (
<TextField
inputType="text"
size="big"
Expand All @@ -246,62 +274,66 @@ const ShowBasicInfoFormContent = ({
name="placeName"
/>
</Styled.TextField>
<Styled.TextFieldRow>
<Styled.TextField flex={2}>
<Controller
control={control}
rules={{
required: true,
}}
render={({ field: { onChange, onBlur, value } }) => (
</Styled.ShowInfoFormContent>
</Styled.ShowInfoFormRow>
<Styled.ShowInfoFormRow>
<Styled.ShowInfoFormContent>
<Styled.ShowInfoFormLabel required>공연장 주소</Styled.ShowInfoFormLabel>
<Styled.TextField>
<Controller
control={control}
rules={{
required: true,
}}
render={({ field: { value } }) => (
<>
<TextField
inputType="text"
size="big"
placeholder="도로명 주소를 입력해 주세요"
placeholder="-"
required
disabled={disabled}
onChange={onChange}
onBlur={() => {
onBlur();
setHasBlurred((prev) => ({ ...prev, placeStreetAddress: true }));
}}
disabled
value={value ?? ''}
errorMessage={
hasBlurred.placeStreetAddress && !value ? '필수 입력사항입니다.' : undefined
}
/>
)}
name="placeStreetAddress"
/>
</Styled.TextField>
<Styled.TextField flex={1}>
<Controller
control={control}
rules={{
required: true,
}}
render={({ field: { onChange, onBlur, value } }) => (
<TextField
inputType="text"
size="big"
placeholder="상세 주소를 입력해 주세요"
required
disabled={disabled}
onChange={onChange}
onBlur={() => {
onBlur();
setHasBlurred((prev) => ({ ...prev, placeDetailAddress: true }));
}}
value={value ?? ''}
errorMessage={
hasBlurred.placeDetailAddress && !value ? '필수 입력사항입니다.' : undefined
}
/>
)}
name="placeDetailAddress"
/>
</Styled.TextField>
</Styled.TextFieldRow>
<Button colorTheme="netural" size="bold" onClick={openDaumPostCodeWithDialog}>
주소 찾기
</Button>
</>
)}
name="placeStreetAddress"
/>
</Styled.TextField>
<Styled.TextField>
<Controller
control={control}
rules={{
required: true,
}}
render={({ field: { onChange, onBlur, value } }) => (
<TextField
ref={detailAdressInputRef}
inputType="text"
size="big"
placeholder="상세 주소를 입력해 주세요"
required
disabled={disabled}
onChange={onChange}
onBlur={() => {
onBlur();
setHasBlurred((prev) => ({ ...prev, placeDetailAddress: true }));
}}
value={value ?? ''}
errorMessage={
hasBlurred.placeDetailAddress && !value ? '필수 입력사항입니다.' : undefined
}
/>
)}
name="placeDetailAddress"
/>
</Styled.TextField>
</Styled.ShowInfoFormContent>
</Styled.ShowInfoFormRow>
</Styled.ShowInfoFormGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ const FileUploadAreaText = styled.span`
const TextField = styled.div<TextFieldProps>`
margin-top: 8px;
display: flex;
align-items: center;
align-items: start;
gap: 8px;
flex: ${({ flex }) => flex};
Expand All @@ -239,16 +239,6 @@ const TextFieldSuffix = styled.span`
flex: 0;
`;

const TextFieldRow = styled.div`
display: flex;
flex-direction: column;
${mq_lg} {
flex-direction: row;
gap: 8px;
}
`;

const TextAreaContainer = styled.div`
position: relative;
display: flex;
Expand Down Expand Up @@ -541,7 +531,6 @@ export default {
FileUploadAreaText,
TextField,
TextFieldSuffix,
TextFieldRow,
TextAreaContainer,
TextArea,
TextAreaErrorMessage,
Expand Down
31 changes: 28 additions & 3 deletions apps/admin/src/components/TicketForm/SalesTicketForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,27 @@ const SalesTicketForm = ({ onSubmit }: SalesTicketFormProps) => {
totalForSale: false,
});

const validatePrice = (price: string) => {
const parsedPrice = Number(price);
return parsedPrice >= 200 || parsedPrice === 0;
};

const handlePriceErrorMessage = (hasBlurred: boolean, price: string) => {
if (hasBlurred && (!price || !validatePrice(price))) {
return '0원 또는 200원 이상을 입력해 주세요.';
}
return '';
};

return (
<Styled.TicketForm onSubmit={handleSubmit(onSubmit)}>
<Styled.TicketFormRow>
<Styled.TicketFormDescription>
<Styled.Description>만들고 싶은 티켓 정보를 입력해 주세요.</Styled.Description>
</Styled.TicketFormRow>
<Styled.SubDescription>
* 퀵계좌이체 지원을 위해 유료 티켓은 200원 이상 입력이 필요합니다.{'\n'}* 무료 티켓 생성을
원하시면 0원을 입력해 주세요.
</Styled.SubDescription>
</Styled.TicketFormDescription>
<Styled.TicketFormRow>
<Styled.TicketFormContent>
<Styled.TicketFormLabel>티켓 이름</Styled.TicketFormLabel>
Expand Down Expand Up @@ -65,15 +81,23 @@ const SalesTicketForm = ({ onSubmit }: SalesTicketFormProps) => {
placeholder="0"
min={0}
{...register('price', { required: true })}
onChange={(event) => {
register('price', {
required: true,
validate: validatePrice,
}).onChange(event);
}}
onBlur={(event) => {
register('price', { required: true }).onBlur(event);
setHasBlurred((prev) => ({ ...prev, price: true }));
}}
errorMessage={hasBlurred.price && !getValues('price') ? '필수 입력사항입니다.' : ''}
errorMessage={handlePriceErrorMessage(hasBlurred.price, getValues('price'))}
/>
<Styled.TextFieldSuffix></Styled.TextFieldSuffix>
</Styled.TextField>
</Styled.TicketFormContent>
</Styled.TicketFormRow>
<Styled.TicketFormRow>
<Styled.TicketFormContent>
<Styled.TicketFormLabel>수량</Styled.TicketFormLabel>
<Styled.TextField>
Expand All @@ -94,6 +118,7 @@ const SalesTicketForm = ({ onSubmit }: SalesTicketFormProps) => {
</Styled.TextField>
</Styled.TicketFormContent>
</Styled.TicketFormRow>

<Styled.TicketFormButton>
<Button type="submit" size="bold" colorTheme="primary" disabled={!isDirty || !isValid}>
생성하기
Expand Down
24 changes: 24 additions & 0 deletions apps/admin/src/components/TicketForm/TicketForm.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,35 @@ const TicketForm = styled.form`
flex-direction: column;
`;

const TicketFormDescription = styled.div`
display: flex;
flex-direction: column;
margin-bottom: 20px;
${mq_lg} {
margin-bottom: 28px;
}
`;

const Description = styled.p`
${({ theme }) => theme.typo.b1};
color: ${({ theme }) => theme.palette.grey.g50};
margin-bottom: 0;
${mq_lg} {
${({ theme }) => theme.typo.b3};
color: ${({ theme }) => theme.palette.grey.g70};
margin-bottom: 4px;
}
`;

const SubDescription = styled.p`
display: none;
${mq_lg} {
display: block;
${({ theme }) => theme.typo.b1};
color: ${({ theme }) => theme.palette.grey.g50};
}
`;

Expand Down Expand Up @@ -76,7 +98,9 @@ const TicketFormButton = styled.div`

export default {
TicketForm,
TicketFormDescription,
Description,
SubDescription,
TicketFormRow,
TicketFormContent,
TicketFormLabel,
Expand Down
Loading

0 comments on commit 5f33509

Please sign in to comment.