Skip to content

Commit

Permalink
Merge branch 'dev' into feat/create-study
Browse files Browse the repository at this point in the history
  • Loading branch information
abiriadev committed May 7, 2024
2 parents e0a03cb + c94e65d commit c2d7c9d
Show file tree
Hide file tree
Showing 89 changed files with 4,420 additions and 1,306 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Unit Tests
on:
push:
branches:
- dev
pull_request:
workflow_dispatch:
jobs:
run:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Enable yarn
run: corepack enable
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: yarn
- name: Install dependencies
run: yarn install
- name: Run unit tests
run: yarn test
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ dist
dist-ssr
*.local

.yarn/cache/*

# Editor directories and files
.vscode/*
!.vscode/extensions.json
Expand Down
1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v20.10.0
10 changes: 10 additions & 0 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ import { ThemeProvider } from 'styled-components';
import { theme } from '@/Styles/theme';
import { GlobalStyle } from '@/Styles/globalStyles';
import { withRouter } from 'storybook-addon-remix-react-router';
import { handlers } from '../src/Mocks/handlers';
import { initialize, mswLoader } from 'msw-storybook-addon';

initialize(
{
onUnhandledRequest: 'bypass',
},
handlers,
);

export default {
parameters: {
Expand Down Expand Up @@ -37,4 +46,5 @@ export default {
),
withRouter,
],
loaders: [mswLoader],
} satisfies Preview;
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ VITE_BASE_API_URL = Base API Endpoint
yarn start:windows
```

### 5. Storybook 실행

```sh
yarn storybook
````

## 📁 Directory Structure
```
Expand Down
13 changes: 13 additions & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export default {
testEnvironment: 'jsdom',
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
moduleNameMapper: {
'^.+\\.svg$': 'jest-svg-transformer',
'\\.(css|less|sass|scss)$': 'identity-obj-proxy',
'^@/(.*)$': '<rootDir>/src/$1',
},
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
moduleDirectories: ['node_modules', '<rootDir>'],
};
1 change: 1 addition & 0 deletions jest.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '@testing-library/jest-dom';
20 changes: 18 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"start:windows": "set HOST=local.ludoapi.store &&yarn dev",
"test": "jest",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
Expand All @@ -20,6 +21,7 @@
"@types/react-datepicker": "^4.19.5",
"@types/styled-components": "^5.1.34",
"axios": "^1.6.7",
"date-fns": "^3.6.0",
"eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-prettier": "^5.1.2",
Expand Down Expand Up @@ -50,9 +52,13 @@
"@storybook/react": "^8.0.8",
"@storybook/react-vite": "^8.0.8",
"@storybook/test": "^8.0.8",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^15.0.2",
"@types/jest": "^29.5.12",
"@types/node": "^20.11.10",
"@types/react": "^18.2.43",
"@types/react-dom": "^18.2.17",
"@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^6.14.0",
"@typescript-eslint/parser": "^6.14.0",
"@vitejs/plugin-react": "^4.2.1",
Expand All @@ -61,17 +67,27 @@
"eslint-plugin-react-refresh": "^0.4.5",
"eslint-plugin-storybook": "^0.8.0",
"husky": "^8.0.3",
"identity-obj-proxy": "^3.0.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"jest-styled-components": "^7.2.0",
"jest-svg-transformer": "^1.0.0",
"msw-storybook-addon": "^2.0.0",
"prettier": "^3.2.5",
"storybook": "^8.0.8",
"storybook-addon-remix-react-router": "^3.0.0",
"ts-jest": "^29.1.2",
"ts-node": "^10.9.2",
"typescript": "^5.2.2",
"vite": "^5.0.8",
"vite-plugin-mkcert": "^1.17.3",
"vite-plugin-svgr": "^4.2.0"
},
"msw": {
"workerDirectory": [
"src/Mocks"
"src/Mocks",
"public"
]
}
},
"packageManager": "[email protected]"
}
26 changes: 25 additions & 1 deletion src/Apis/recruitment.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { httpClient } from '@/utils/axios';
import { PopularRecruitments, Recruitments, FilterOptionParams, RecruitmentDetail } from '@/Types/study';
import {
PopularRecruitments,
Recruitments,
FilterOptionParams,
RecruitmentDetail,
RecruitmentForm,
} from '@/Types/study';
import { API_END_POINT } from '@/Constants/api';
import { getFilterOptions } from '@/utils/filter';

Expand All @@ -21,8 +27,26 @@ export const getRecruitments = (
});
};

// 모집공고 생성
export const createRecruitment = (
studyId: number,
body: RecruitmentForm,
): Promise<{ data: { data: RecruitmentDetail } }> => httpClient.post(API_END_POINT.CREATE_RECRUITMENT(studyId), body);

// TODO: 모집공고 수정 - 추후 data type 변경, location 헤더만 내리는 방식으로 개선 예정
export const editRecruitment = (
studyId: number,
body: RecruitmentForm,
): Promise<{ data: { data: RecruitmentDetail } }> => httpClient.put(API_END_POINT.EDIT_RECRUITMENT(studyId), body);

// 모집공고 조회
export const getRecruitmentDetail = (recruitmentId: number): Promise<{ data: { data: RecruitmentDetail } }> =>
httpClient.get(API_END_POINT.RECRUITMENT(recruitmentId));

// 모집공고 삭제
export const deleteRecruitment = (studyId: number): Promise<{ data: { data: RecruitmentDetail } }> =>
httpClient.get(API_END_POINT.DELETE_RECRUITMENT(studyId));

// ???
export const closeRecruitment = (studyId: number) =>
httpClient.patch(API_END_POINT.CLOSE_RECRUITMENT(studyId), null, { params: { status: 'RECRUITED' } });
8 changes: 8 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ import { RouterPath } from './Router/index.tsx';
import LoginProvider from './Providers/LoginProvider/index.tsx';
import ReactQueryProvider from './Providers/QueryProvider/index.tsx';

if (process.env.NODE_ENV === 'development') {
const { worker } = await import('./Mocks/browser');

worker.start({
onUnhandledRequest: 'bypass',
});
}

const App = () => {
return (
<ReactQueryProvider showDevTools>
Expand Down
2 changes: 1 addition & 1 deletion src/Assets/SearchIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const SearchIcon = () => {
clip-rule="evenodd"
d="M9.68274 16.3656C7.89774 16.3656 6.21954 15.6705 4.95744 14.4084C3.69534 13.1463 3.00024 11.4681 3.00024 9.68311C3.00024 7.89811 3.69534 6.21991 4.95744 4.95781C6.21954 3.69571 7.89774 3.00061 9.68274 3.00061C11.4677 3.00061 13.1459 3.69571 14.408 4.95781C15.6701 6.21991 16.3652 7.89811 16.3652 9.68311C16.3652 11.2665 15.8183 12.7659 14.8138 13.9653L15.5256 14.6772L15.8504 14.3523C16.3103 13.8924 17.0585 13.8924 17.5181 14.3523L17.9774 14.8116L17.9773 14.8118L18.0974 14.9319C18.32 15.1545 18.4427 15.4509 18.4427 15.7659C18.4427 15.8803 18.4266 15.9921 18.3953 16.0989C19.5324 17.2361 20.1883 17.9037 20.5202 18.2619C20.8355 18.6021 20.9999 18.7938 20.9999 19.0968C20.9999 19.3506 20.9012 19.5888 20.7218 19.7682L20.2448 20.2452V20.2449L19.7679 20.7219C19.5885 20.9013 19.35 21 19.0965 21C18.8427 21 18.6045 20.9013 18.4251 20.7219L16.0984 18.3953C15.9915 18.4266 15.8794 18.4428 15.7649 18.4428H15.7655C15.4505 18.4428 15.1544 18.3201 14.9315 18.0975L14.8115 17.9775L14.4722 17.6382L14.3522 17.5182C13.8923 17.0583 13.8923 16.3101 14.3522 15.8505L14.6771 15.5257L13.9653 14.8139C12.7658 15.8186 11.2663 16.3656 9.68274 16.3656ZM15.3206 16.7895L15.3207 16.7894L15.7655 17.2342L16.4996 16.5L17.348 17.3484L17.0482 17.6482L19.0965 19.6965L19.3964 19.3965L19.3965 19.3965L19.6766 19.1163C19.2969 18.7038 18.4377 17.8386 17.6485 17.0489L17.3483 17.349V17.3484L16.4999 16.5L17.2343 15.7656L16.7897 15.321L16.7899 15.3209L16.6844 15.2154L15.95 15.9498H15.9497L15.2153 16.6842L15.3206 16.7895ZM9.68274 4.20001C6.65964 4.20001 4.19994 6.65971 4.19994 9.68281C4.19994 12.7059 6.65964 15.1656 9.68274 15.1656C12.7058 15.1656 15.1655 12.7062 15.1655 9.68281C15.1655 6.65941 12.7061 4.20001 9.68274 4.20001Z"
fill="black"
fill-opacity="0.45"
fillOpacity="0.45"
/>
</g>
</g>
Expand Down
2 changes: 1 addition & 1 deletion src/Assets/SelectArrow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const SelectArrow = () => {
id="Vector"
d="M20.9999 7.92031C20.9999 8.07391 20.9414 8.22751 20.8241 8.34451L12.8339 16.335C12.374 16.7949 11.6258 16.7949 11.1662 16.335L3.17572 8.34451C2.94142 8.11021 2.94142 7.73041 3.17572 7.49611C3.41002 7.26181 3.78982 7.26181 4.02412 7.49611L11.9999 15.4719L19.9757 7.49611C20.21 7.26181 20.5898 7.26181 20.8241 7.49611C20.9414 7.61341 20.9999 7.76671 20.9999 7.92031Z"
fill="black"
fill-opacity="0.45"
fillOpacity="0.45"
/>
</svg>
);
Expand Down
3 changes: 3 additions & 0 deletions src/Assets/icons/setting.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions src/Assets/icons/studyThumbnail.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/Assets/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export { default as Loading } from './icons/lodaing.svg?react';
export { default as Logout } from './icons/logout.svg?react';
export { default as Article } from './icons/article.svg?react';
export { default as Study } from './icons/study.svg?react';
export { default as StudyThumbnail } from './icons/studyThumbnail.svg?react';
export { default as Setting } from './icons/setting.svg?react';

// Logo
export { default as BlankLogo } from './images/blank-logo.png';
Expand Down
93 changes: 50 additions & 43 deletions src/Components/Calendar/EndDate.tsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,61 @@
// react-datepicker를 사용해서 마감날짜 구현 328px, 44px, ex) 24.01.23
import DatePicker from 'react-datepicker';
import { useState } from 'react';
import React, { useState } from 'react';
import { ControllerRenderProps } from 'react-hook-form';

// date-picker
import DatePicker, { ReactDatePicker } from 'react-datepicker';
import { registerLocale } from 'react-datepicker';
import ko from 'date-fns/locale/ko';
import 'react-datepicker/dist/react-datepicker.css';
import { parseISOString } from '@/utils/date';
import styled from 'styled-components';
import { OptionalCreates } from '@/Pages/Studies/CreateRecruitment';
import { Creates } from '@/Types/studies';

export type Props = {
onClick?: () => void;
children?: React.ReactNode;
// onChange?: (event: string) => void;
setForm: (any: OptionalCreates) => void;
useForm: Creates;
value?: string;
type?: string;
name?: string;
maxlength?: number;
id?: string;
formData?: number | string;
ref?: string;
};

export const EndDate = ({ useForm }: Props) => {
const [startDateTime, setForms] = useState(new Date());

return (
<DateContainer
value={(useForm.recruitmentEndDateTime = startDateTime.toISOString().slice(0, -5))}
selected={startDateTime}
dateFormat="yy.MM.dd"
onChange={(date: Date) => setForms(date)}
placeholderText="ex)24.01.07"
isClearable={true}
/>
);
};

registerLocale('ko', ko);

interface IFormValues {
recruitmentEndDateTime: string;
}

interface Props {
defaultValue?: string;
}

export const EndDate = React.forwardRef<ReactDatePicker<string, boolean>, ControllerRenderProps<IFormValues> & Props>(
({ onChange, name, defaultValue }, ref) => {
const today = new Date();
const [startDate, setStartDate] = useState<Date>(defaultValue && new Date(defaultValue));

return (
<DateContainer
name={name}
locale="ko"
selected={startDate}
dateFormat="yy.MM.dd"
minDate={today}
onChange={(date) => {
onChange(parseISOString(date));
if (date instanceof Array) setStartDate(date[1]);
else setStartDate(date);
}}
placeholderText="ex)24.01.07"
isClearable={false}
ref={ref}
shouldCloseOnSelect // 날짜를 선택하면 자동으로 닫힌다
autoComplete="off"
/>
);
},
);

const DateContainer = styled(DatePicker)`
width: 328px;
width: 100%;
height: 24px;
background-color: ${(props) => props.theme.color.gray3};
align-items: center;
align-self: stretch;
border: 1px solid #cbcdd1;
border-width: 0;
background: ${(props) => props.theme.color.gray1};
resize: none;
flex: 1 0 0;
margin-top: 10px;
padding-bottom: 10px;
padding-right: 16px;
padding-left: 16px;
&::placeholder {
color: ${(props) => props.theme.color.black2};
}
`;
Loading

0 comments on commit c2d7c9d

Please sign in to comment.