Skip to content
Merged
Show file tree
Hide file tree
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
49 changes: 46 additions & 3 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"next": "14.2.32",
"react": "^18",
"react-dom": "^18",
"react-responsive": "^10.0.1",
"tailwind-merge": "^3.3.1"
},
"devDependencies": {
Expand Down
50 changes: 50 additions & 0 deletions src/api/employer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import axios from '@/lib/axios';
import RegisterFormData from '@/types/myShop';
import { default as originAxios } from 'axios';

export async function postShop(body: RegisterFormData) {
const { address1, address2, category, description, name, originalHourlyPay, image } = body;

const imageUrl = image
? `https://bootcamp-project-api.s3.ap-northeast-2.amazonaws.com/${image.name}`
: '';

const tmpBody = {
address1,
address2,
category,
description,
name,
originalHourlyPay,
imageUrl,
};
const { data } = await axios.post('/shops', tmpBody);
}

export async function postPresignedUrl(imageName: string) {
const { data } = await axios.post('/images', { name: imageName });
console.log(data);
return data.item.url;
}

export async function uploadImage(presignedUrl: string, file: File) {
const result = await originAxios.put(presignedUrl, file);
}

export async function getPresignedUrl(presignedUrl: string) {
// 1. URL 객체 생성
const url = new URL(presignedUrl);

// 2. 쿼리 파라미터를 제거 (URL 객체의 search 속성을 비움)
url.search = '';

// 3. 쿼리 파라미터가 제거된 새 URL 문자열을 얻습니다.
const baseUrl = url.toString();

const result = await originAxios.get(baseUrl);
}

export async function getShop(shopId: string) {
const { data } = await axios.get(`/shops/${shopId}`);
return data;
}
43 changes: 43 additions & 0 deletions src/components/features/my-shop/registerAddress.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Dropdown, Input } from '@/components/ui';
import { ADDRESS_CODE } from '@/constants/dropdown';
import RegisterFormData from '@/types/myShop';

interface Props {
formData: RegisterFormData;
handleChange: (key: keyof RegisterFormData, value: string) => void;
}

const RegisterAddress = ({ formData, handleChange }: Props) => {
return (
<>
<div className='flex flex-col gap-6 tablet:flex-row'>
<div className='flex flex-col gap-1 tablet:w-1/2'>
<div>
<span>주소</span>
<span className='ml-0.5 text-red-500'>*</span>
</div>
<Dropdown
name='staus'
ariaLabel='어드레스'
placeholder='선택'
values={ADDRESS_CODE}
selected={formData.address1}
onChange={val => handleChange('address1', val)}
className='w-full'
/>
</div>
<div className='flex flex-col gap-2 tablet:w-1/2'>
<Input
label='상세 주소'
requiredMark
value={formData.address2}
onChange={e => handleChange('address2', e.target.value)}
placeholder='입력'
/>
</div>
</div>
</>
);
};

export default RegisterAddress;
24 changes: 24 additions & 0 deletions src/components/features/my-shop/registerDescription.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import RegisterFormData from '@/types/myShop';

interface Props {
formData: RegisterFormData;
handleChange: (key: keyof RegisterFormData, value: string) => void;
}

const RegisterDescription = ({ formData, handleChange }: Props) => {
return (
<>
<div className='flex flex-col gap-1'>
<span>가게 설명</span>
<textarea
value={formData.description}
placeholder='입력'
className={'base-input h-[153px] resize-none'}
onChange={e => handleChange('description', e.target.value)}
></textarea>
</div>
</>
);
};

export default RegisterDescription;
39 changes: 39 additions & 0 deletions src/components/features/my-shop/registerImage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Icon } from '@/components/ui';
import Image from 'next/image';
import { ChangeEvent } from 'react';

interface Props {
preview: string | null;
handleImageChange: (e: ChangeEvent<HTMLInputElement>) => void;
}

const RegisterImage = ({ preview, handleImageChange }: Props) => {
return (
<>
<div className='flex flex-col gap-1'>
<div>
<span>가게 이미지</span>
<span className='ml-0.5 text-red-500'>*</span>
</div>
<label className='relative flex h-[200px] w-full cursor-pointer flex-col items-center justify-center overflow-hidden rounded-xl border border-gray-300 tablet:h-[276px] tablet:w-[483px]'>
{preview ? (
<Image src={preview} alt='미리보기' fill />
) : (
<>
<Icon
iconName='camera'
iconSize='lg'
ariaLabel='카메라 아이콘'
className='bg-gray-400'
/>
<p className='text-gray-400'>이미지 추가하기</p>
</>
)}
<input type='file' accept='image/*' className='hidden' onChange={handleImageChange} />
</label>
</div>
</>
);
};

export default RegisterImage;
57 changes: 57 additions & 0 deletions src/components/features/my-shop/registerModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Modal } from '@/components/ui';
import { useRouter } from 'next/router';

interface Props {
openWarning: boolean;
setOpenWarning: (value: boolean) => void;
openCancel: boolean;
setOpenCancel: (value: boolean) => void;
openConfirm: boolean;
setOepnConfirm: (value: boolean) => void;
}

const RegisterModal = ({
openWarning,
setOpenWarning,
openCancel,
setOpenCancel,
openConfirm,
setOepnConfirm,
}: Props) => {
const router = useRouter();
return (
<>
<Modal
open={openWarning}
onClose={() => setOpenWarning(false)}
variant='warning'
title='필수 항목을 작성해주세요.'
primaryText='확인'
onPrimary={() => setOpenWarning(false)}
/>
<Modal
open={openCancel}
onClose={() => setOpenCancel(false)}
variant='warning'
title='취소하시겠습니까?'
primaryText='아니요'
secondaryText='예'
onSecondary={() => {
setOpenCancel(false);
router.push('/my-shop');
}}
onPrimary={() => setOpenCancel(false)}
/>
<Modal
open={openConfirm}
onClose={() => setOepnConfirm(false)}
variant='success'
title='등록이 완료되었습니다.'
primaryText='확인'
onPrimary={() => router.push('/my-shop')}
/>
</>
);
};

export default RegisterModal;
43 changes: 43 additions & 0 deletions src/components/features/my-shop/registerName.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Dropdown, Input } from '@/components/ui';
import { CATEGORY_CODE } from '@/constants/dropdown';
import RegisterFormData from '@/types/myShop';

interface Props {
formData: RegisterFormData;
handleChange: (key: keyof RegisterFormData, value: string) => void;
}

const RegisterName = ({ formData, handleChange }: Props) => {
return (
<>
<div className='flex flex-col gap-6 tablet:flex-row'>
<div className='flex flex-col gap-2 tablet:w-1/2'>
<Input
label='가게 이름'
requiredMark
value={formData.name}
onChange={e => handleChange('name', e.target.value)}
placeholder='입력'
/>
</div>
<div className='flex flex-col gap-1 tablet:w-1/2'>
<div>
<span>분류</span>
<span className='ml-0.5 text-red-500'>*</span>
</div>
<Dropdown
name='staus'
ariaLabel='카테고리'
placeholder='선택'
values={CATEGORY_CODE}
selected={formData.category}
onChange={val => handleChange('category', val)}
className='w-full'
/>
</div>
</div>
</>
);
};

export default RegisterName;
Loading