Skip to content

Commit

Permalink
build: 프로젝트 초기 세팅
Browse files Browse the repository at this point in the history
- userTypeStore 생성
- import 오류 수정
  • Loading branch information
junghaesung79 committed Jun 12, 2024
1 parent 7519041 commit b790ffc
Show file tree
Hide file tree
Showing 15 changed files with 250 additions and 68 deletions.
15 changes: 13 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
import { Suspense } from 'react';
import { Suspense, useEffect } from 'react';

import { Route, Routes } from 'react-router-dom';
import { Route, Routes, useNavigate } from 'react-router-dom';

import useErrorBoundary from 'hooks/useErrorBoundary';

Check warning on line 5 in src/App.tsx

View workflow job for this annotation

GitHub Actions / ESLint

'useErrorBoundary' is defined but never used

Check warning on line 5 in src/App.tsx

View workflow job for this annotation

GitHub Actions / ESLint

'useErrorBoundary' is defined but never used
import AuthLayout from 'layout/AuthLayout';
import DefaultLayout from 'layout/DefaultLayout';
import Coop from 'pages/Coop';
import Login from 'pages/Login';
import useUserTypeStore from 'store/useUserTypeStore';

function App() {
const navigate = useNavigate();
const { userType } = useUserTypeStore();

useEffect(() => {
if (!userType) {
navigate('/login', { replace: true });
}
}, [userType, navigate]);

return (
<Suspense fallback={<div />}>
<Routes>
Expand Down
23 changes: 23 additions & 0 deletions src/api/uploadFile/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { accessClient } from 'api';

interface File {
content_length: number;
content_type: string;
file_name: string;
}

export interface FileResponse {
pre_signed_url: string;
file_url: string;
expiration_date: string;
}

export const uploadFile = (formData: FormData) => accessClient.post('/OWNERS/upload/file', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
}).catch((error) => Promise.reject(error));

export const uploadFiles = (formData: FormData) => accessClient.post('/OWNERS/upload/files', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
});

export const getCoopUrl = (fileName: File) => accessClient.post<FileResponse>('/coop/upload/url', fileName);
88 changes: 88 additions & 0 deletions src/components/CustomButton/CustomButton.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
.button {
&--large {
font-size: 16px;
width: 100%;
background-color: #175c8e;
color: #ffffff;
border: none;
height: 48px;

&:hover {
cursor: pointer;
}

&:disabled {
background-color: #c4c4c4;

&:hover {
cursor: auto;
}
}
}

&--small {
font-size: 14px;
width: 80px;
background-color: #175c8e;
color: #ffffff;
border: none;
height: 48px;
padding: 0 10px;

&:hover {
cursor: pointer;
}

&:disabled {
background-color: #c4c4c4;

&:hover {
cursor: auto;
}
}
}

&--mobile {
width: 48%;
height: 48px;
font-weight: 500;
font-size: 15px;
background-color: #175c8e;
color: #ffffff;
border: none;

&:hover {
cursor: pointer;
}

&:disabled {
background-color: #c4c4c4;

&:hover {
cursor: auto;
}
}
}

&--mobile-small {
width: 83px;
height: 37px;
font-weight: 500;
font-size: 15px;
background-color: #175c8e;
color: #ffffff;
border: none;

&:hover {
cursor: pointer;
}

&:disabled {
background-color: #c4c4c4;

&:hover {
cursor: auto;
}
}
}
}
25 changes: 25 additions & 0 deletions src/components/CustomButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import styles from './CustomButton.module.scss';

interface ButtonProps {
content:string,
// 80px | 부모 요소의 절반 width | 부모요소 전체 width | 83px
buttonSize: 'small' | 'mobile' | 'large' | 'mobile-small',
disable?: boolean,
submit?:boolean
onClick?: () => void
}

export default function CustomButton({
content, buttonSize, disable, onClick, submit,
}:ButtonProps) {
return (
<button
type={submit ? 'submit' : 'button'}
className={`${styles[`button--${buttonSize}`]}`}
onClick={onClick}
disabled={!!disable}
>
{content}
</button>
);
}
9 changes: 8 additions & 1 deletion src/models/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,19 @@ export const RefreshResponse = z.object({

export type RefreshResponse = z.infer<typeof RefreshResponse>;

export const UserType = z.union([
z.literal('COOP'),
z.null(),
]);

export type UserType = z.infer<typeof UserType>;

export const CoopMeResponse = z.object({
email: z.string(),
gender: z.number(),
name: z.string(),
phone_number: z.number(),
user_type: z.string(),
user_type: UserType,
});

export type CoopMeResponse = z.infer<typeof CoopMeResponse>;
4 changes: 2 additions & 2 deletions src/models/dinings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const PlaceSchema = z.union([
z.literal('2캠퍼스'),
]);

export const Dinings = z.object({
export const Dining = z.object({
id: z.number(),
date: z.string(),
type: DiningTypeSchema,
Expand All @@ -44,4 +44,4 @@ export const Dinings = z.object({
changed_at: z.string().nullable(),
});

export type Dinings = z.infer<typeof Dinings>;
export type Dining = z.infer<typeof Dining>;
17 changes: 9 additions & 8 deletions src/pages/Coop/components/MenuCard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/* eslint-disable no-nested-ternary */
import { useEffect, useRef, useState } from 'react';

import { getCoopUrl } from 'api/uploadFile';
import Photo from 'assets/svg/coop/photo.svg?react';
import SoldOut from 'assets/svg/coop/sold-out.svg?react';
import { DiningPlace, Dinings, DiningType } from 'models/dinings';
import { DiningPlace, Dining, DiningType } from 'models/dinings';
import SoldOutModal from 'pages/Coop/components/SoldOutModal';
import SoldOutToggle from 'pages/Coop/components/SoldOutToggle';
import SoldOutToggle from 'pages/Coop/components/SoldOutToggleButton';
import { getOpenMenuType, OperatingStatus, OPEN } from 'pages/Coop/hook/useGetCurrentMenuType';
import { useUploadDiningImage, useSoldOut } from 'query/coop';
import { useGetDining } from 'query/dinings';
Expand All @@ -29,7 +30,7 @@ export default function MenuCard({ selectedMenuType, selectedDate }: MenuCardPro
const { updateSoldOut: updateSoldOutMutation } = useSoldOut();
const fileInputRefs = useRef<{ [key: number]: HTMLInputElement | null }>({});
const [isSoldOutModalOpen, setIsSoldOutModalOpen] = useState(false);
const [selectedMenu, setSelectedMenu] = useState<Dinings | null>(null);
const [selectedMenu, setSelectedMenu] = useState<Dining | null>(null);
const [selectedPlace, setSelectedPlace] = useState<DiningPlace | null>(null);
const [formmatDate, setFormmatDate] = useState<string>('');
const { data } = useGetDining(formmatDate);
Expand Down Expand Up @@ -69,16 +70,16 @@ export default function MenuCard({ selectedMenuType, selectedDate }: MenuCardPro
fileInputRefs.current[menuId]?.click();
};

const filteredData = data?.filter((menu: Dinings) => ['A코너', 'B코너', 'C코너'].includes(menu.place));
const filteredData = data?.filter((menu: Dining) => ['A코너', 'B코너', 'C코너'].includes(menu.place));

const getDiningDataForCorner = (place: DiningPlace, diningData: Dinings[]):
Dinings | null => diningData.find(
const getDiningDataForCorner = (place: DiningPlace, diningData: Dining[]):
Dining | null => diningData.find(
(menu) => menu.place === place,
) || null;

const handleToggleSoldOutModal = (menu: Dinings, type: DiningType) => {
const handleToggleSoldOutModal = (menu: Dining) => {
setSelectedMenu(menu || null);
setSelectedPlace(type || null);
setSelectedPlace(menu.place || null);
if (menu?.soldout_at === null) {
setIsSoldOutModalOpen((prev) => !prev);
} else if (menu) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,4 @@
cursor: pointer;
-webkit-tap-highlight-color: rgb(0 0 0 / 0%);
-webkit-tap-highlight-color: transparent;

.background,
.circle {
rx: 9.5;
stroke-width: 3;
}
}
31 changes: 31 additions & 0 deletions src/pages/Coop/components/SoldOutToggleButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Dining } from 'models/dinings';
import useToggleStore from 'store/useToggleStore';

import styles from './SoldOutToggleButton.module.scss';

interface Props {
onClick: () => void;
menu: Dining;
}

function SoldOutToggleButton({ onClick, menu }: Props) {
const { toggleSoldOut } = useToggleStore();
const handleToggle = () => {
onClick();
toggleSoldOut(menu.id);
};

return (
<div>
<button
type="button"
className={styles['toggle-button']}
onClick={handleToggle}
>
버튼
</button>
</div>
);
}

export default SoldOutToggleButton;
2 changes: 1 addition & 1 deletion src/pages/Coop/components/SoldoutModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect } from 'react';

import CustomButton from 'page/Auth/Signup/component/CustomButton';
import CustomButton from 'components/CustomButton';
import cn from 'utils/className';

import { createPortal } from 'react-dom';
Expand Down
42 changes: 0 additions & 42 deletions src/pages/Coop/components/SoldoutToggle/index.tsx

This file was deleted.

6 changes: 3 additions & 3 deletions src/pages/Coop/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useState } from 'react';

import Calendar from 'pages/Coop/components/Calendar';
import MenuCard from 'pages/Coop/components/MenuCard';
import MenuType from 'pages/Coop/components/MenuType';
import { getCurrentMenuType } from 'pages/Coop/hook/useGetCurrentMenuType';

import dayjs from 'dayjs';

import Calendar from './components/Calendar';
import MenuCard from './components/MenuCard';
import MenuType from './components/MenuType';
import styles from './Coop.module.scss';

export default function Coop() {
Expand Down
29 changes: 27 additions & 2 deletions src/query/auth.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useNavigate } from 'react-router-dom';

import { postLogin, postRefresh, postLogout } from 'api/auth';
import { LoginForm, RefreshParams } from 'models/auth';
import { getCoopMe, postLogin, postLogout } from 'api/auth';
import { LoginForm } from 'models/auth';
import { useErrorMessageStore } from 'store/useErrorMessageStore';
import useUserTypeStore from 'store/useUserTypeStore';

import { isKoinError, sendClientError } from '@bcsdlab/koin';
import { useMutation } from '@tanstack/react-query';
Expand Down Expand Up @@ -86,3 +87,27 @@ export const useLogout = () => {

return { logout: mutate, error, isError };
};

export const useCoopMe = () => {
const { setUserType } = useUserTypeStore();

const {
mutate, error, isError, isSuccess,
} = useMutation({
mutationFn: () => getCoopMe(),
onSuccess: async (data) => {
if (data.user_type) {
setUserType(data.user_type);
}
},
onError: (err) => {
if (isKoinError(err)) {
console.error(err);

Check warning on line 105 in src/query/auth.ts

View workflow job for this annotation

GitHub Actions / ESLint

Unexpected console statement
}
},
});

return {
getCoopInfo: mutate, error, isError, isSuccess,
};
};
Loading

0 comments on commit b790ffc

Please sign in to comment.