Skip to content

Commit

Permalink
Merge pull request #159 from UPbrella/develop
Browse files Browse the repository at this point in the history
deploy
ShinChanU authored Sep 25, 2023

Verified

This commit was signed with the committer’s verified signature.
yihuang yihuang
2 parents fd1acd1 + 93e6053 commit f6446e7
Showing 99 changed files with 2,375 additions and 687 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/release-dev.yml
Original file line number Diff line number Diff line change
@@ -37,11 +37,17 @@ jobs:
VITE_NAVER_MAP_API_KEY: ${{ secrets.VITE_NAVER_MAP_API_KEY }}
VITE_KAKAO_MAP_API_KEY: ${{ secrets.VITE_KAKAO_MAP_API_KEY }}
VITE_KAKAO_LOGIN_REST_API_KEY: ${{ secrets.VITE_KAKAO_LOGIN_REST_API_KEY }}
VITE_EMAIL_SERVICE_ID: ${{ secrets.VITE_EMAIL_SERVICE_ID }}
VITE_EMAIL_TEMPLATE_ID: ${{ secrets.VITE_EMAIL_TEMPLATE_ID}}
VITE_EMAIL_PUB_KEY: ${{ secrets.VITE_EMAIL_PUB_KEY}}
run: |
echo "VITE_UPBRELLA_API_BASE_URL=${VITE_UPBRELLA_API_BASE_URL}" >> .env
echo "VITE_NAVER_MAP_API_KEY=${VITE_NAVER_MAP_API_KEY}" >> .env
echo "VITE_KAKAO_MAP_API_KEY=${VITE_KAKAO_MAP_API_KEY}" >> .env
echo "VITE_KAKAO_LOGIN_REST_API_KEY=${VITE_KAKAO_LOGIN_REST_API_KEY}" >> .env
echo "VITE_EMAIL_SERVICE_ID"=${VITE_EMAIL_SERVICE_ID} >> .env
echo "VITE_EMAIL_TEMPLATE_ID"=${VITE_EMAIL_TEMPLATE_ID} >> .env
echo "VITE_EMAIL_PUB_KEY"=${VITE_EMAIL_PUB_KEY} >> .env
- name: Set node@v1
uses: actions/setup-node@v3
6 changes: 6 additions & 0 deletions .github/workflows/release-production.yml
Original file line number Diff line number Diff line change
@@ -55,11 +55,17 @@ jobs:
VITE_NAVER_MAP_API_KEY: ${{ secrets.VITE_NAVER_MAP_API_KEY }}
VITE_KAKAO_MAP_API_KEY: ${{ secrets.VITE_KAKAO_MAP_API_KEY }}
VITE_KAKAO_LOGIN_REST_API_KEY: ${{ secrets.VITE_KAKAO_LOGIN_REST_API_KEY }}
VITE_EMAIL_SERVICE_ID: ${{ secrets.VITE_EMAIL_SERVICE_ID }}
VITE_EMAIL_TEMPLATE_ID: ${{ secrets.VITE_EMAIL_TEMPLATE_ID}}
VITE_EMAIL_PUB_KEY: ${{ secrets.VITE_EMAIL_PUB_KEY}}
run: |
echo "VITE_UPBRELLA_API_BASE_URL=${VITE_UPBRELLA_API_BASE_URL}" >> .env
echo "VITE_NAVER_MAP_API_KEY=${VITE_NAVER_MAP_API_KEY}" >> .env
echo "VITE_KAKAO_MAP_API_KEY=${VITE_KAKAO_MAP_API_KEY}" >> .env
echo "VITE_KAKAO_LOGIN_REST_API_KEY=${VITE_KAKAO_LOGIN_REST_API_KEY}" >> .env
echo "VITE_EMAIL_SERVICE_ID"=${VITE_EMAIL_SERVICE_ID} >> .env
echo "VITE_EMAIL_TEMPLATE_ID"=${VITE_EMAIL_TEMPLATE_ID} >> .env
echo "VITE_EMAIL_PUB_KEY"=${VITE_EMAIL_PUB_KEY} >> .env
- name: Set up Node.js
uses: actions/setup-node@v3
9 changes: 9 additions & 0 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
@@ -18,6 +18,7 @@
"lint-staged": "lint-staged"
},
"dependencies": {
"@emailjs/browser": "^3.11.0",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.11.16",
60 changes: 35 additions & 25 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -13,6 +13,9 @@ import "primereact/resources/primereact.min.css"; //core css
import "primeicons/primeicons.css";
import PrivateRoutes from "./utils/PrivateRoutes";
import { Suspense } from "react";
import UpbrellaStoryPage from "@/components/pages/story/UpbrellaStoryPage";
import AdminRoutes from "@/utils/AdminRoutes";
import InfoPage from "@/components/pages/Info/InfoPage";

const queryClient = new QueryClient({
defaultOptions: {
@@ -42,22 +45,29 @@ function App() {
},
}}
/>
<div className="bg-cover bg-basic">
<div className="max-w-[1440px] min-h-[100vh] px-40 mx-auto flex flex-col sm:px-0">
<Routes>
{/* Not Found Page */}
{/* Route */}
<Route element={<MainLayout />}>
<>
{LAYOUT_ROUTES.map((route) => {
return (
<Route key={route.name} path={route.path} element={<route.component />} />
);
})}
<Route path="/*" element={<NotFound />} />
</>
</Route>
<Route element={<MainLayout />}>

<div className="bg-cover">
<Routes>
{/* width full */}
<Route path={"/about"} element={<UpbrellaStoryPage />} />
<Route path="/" element={<UpbrellaStoryPage />} />
<Route path="/information" element={<InfoPage />} />

{/* width fix */}
<Route element={<MainLayout />}>
<>
{LAYOUT_ROUTES.map((route) => {
return (
<Route key={route.name} path={route.path} element={<route.component />} />
);
})}
<Route path="/*" element={<NotFound />} />
</>
</Route>

{/* admin */}
<Route element={<MainLayout />}>
<Route element={<AdminRoutes />}>
{ADMIN_ROUTES.map((route) => {
return (
<Route
@@ -72,15 +82,15 @@ function App() {
);
})}
</Route>
<Route element={<PrivateRoutes />}>
{NOT_LAYOUT_ROUTES.map((route) => {
return (
<Route key={route.name} path={route.path} element={<route.component />} />
);
})}
</Route>
</Routes>
</div>
</Route>

{/* login */}
<Route element={<PrivateRoutes />}>
{NOT_LAYOUT_ROUTES.map((route) => {
return <Route key={route.name} path={route.path} element={<route.component />} />;
})}
</Route>
</Routes>
</div>
</QueryClientProvider>
</Suspense>
24 changes: 24 additions & 0 deletions src/api/feedBackApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { $axios } from "@/lib/axios";
import { TApiResponse } from "@/types/commonTypes";
import { TConditionRes, TImprovementRes } from "@/types/admin/FeedBackTypes";

const API = {
HISTORIES_STATUS: () => `/admin/rent/histories/status`,
HISTORIES_IMPROVEMENTS: () => `/admin/rent/histories/improvements`,
} as const;

// 신고 내역 조회
export const getHistoriesStatus = async () => {
const res = await $axios.get<TApiResponse<TConditionRes>>(API.HISTORIES_STATUS(), {
withCredentials: true,
});
return res.data;
};

// 개선 요청 내역 조회
export const getHistoriesImprovements = async () => {
const res = await $axios.get<TApiResponse<TImprovementRes>>(API.HISTORIES_IMPROVEMENTS(), {
withCredentials: true,
});
return res.data;
};
15 changes: 13 additions & 2 deletions src/api/storeApi.ts
Original file line number Diff line number Diff line change
@@ -18,13 +18,15 @@ const API = {
ADMIN_IMAGE_UPLOAD: (id: number) => `/admin/stores/${id}/images`,
ADMIN_IMAGE_DELETE: (id: number) => `/admin/stores/images/${id}`,
ADMIN_CLASSIFICATIONS: (id?: number) =>
id ? `/admin/stores/classifications/${id}` : "/admin/stores/classifications/",
id ? `/stores/classifications/${id}` : "/stores/classifications/",
CLASSIFICATIONS: () => "/stores/classifications",
ADMIN_SUBCLASSIFICATIONS: (id?: number) =>
id ? `/admin/stores/subClassifications/${id}` : "/stores/subClassifications",
id ? `/stores/subClassifications/${id}` : "/stores/subClassifications",
STORE_CLASSIFICATIONS: (id: number) => `/stores/classification/${id}`,
STORE_LIST: () => "/stores/introductions",
STORE_DETAIL: (id: number) => `/stores/${id}`,
ADMIN_STORES_PATCH_ACTIVE: (storeId: number) => `/admin/stores/${storeId}/activate`,
ADMIN_STORES_PATCH_INACTIVE: (storeId: number) => `/admin/stores/${storeId}/inactivate`,
} as const;

// 협업지점 소개 페이지에서의 협업지점 목록 조회
@@ -115,3 +117,12 @@ export const postSubClassification = async (params: TSubClassificationParams) =>
export const deleteSubClassification = async (deleteId: number) => {
await $axios.delete(API.ADMIN_SUBCLASSIFICATIONS(deleteId));
};

// 협업지점 활성화, 비활성화
export const patchStoreActive = async (storeId: number) => {
await $axios.patch(API.ADMIN_STORES_PATCH_ACTIVE(storeId));
};

export const patchStoreInactive = async (storeId: number) => {
await $axios.patch(API.ADMIN_STORES_PATCH_INACTIVE(storeId));
};
Binary file added src/assets/Story/main_section1_bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Story/section3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Story/section4-1.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Story/section4-2.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Story/section4-3.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Story/section4-4.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Story/section5_bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Story/section8_bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions src/assets/empty_states_img.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions src/components/atoms/Contact/Button/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export type TButtonProps = {
isActive: boolean;
};

const Button = ({ isActive }: TButtonProps) => {
return (
<div>
<button
type="submit"
className={`w-full h-48 bg-primary-500 rounded-8 text-white text-16 leading-24 font-semibold ${
isActive ? "" : "opacity-50 cursor-not-allowed"
}`}
disabled={!isActive}
>
문의하기
</button>
</div>
);
};

export default Button;
28 changes: 28 additions & 0 deletions src/components/atoms/Contact/Input/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export type ContactInputProps = {
label: string;
optional?: boolean;
placeholder: string;
setValue: (value: string) => void;
name: string;
value?: string;
};

const Input = ({ label, optional, placeholder, setValue, name, value }: ContactInputProps) => {
return (
<div className="flex flex-col p-5 mb-32 w-full">
<div className="flex items-center">
<div className="flex items-center mb-4 text-gray-700 text-15 leading-22 mr-4">{label}</div>
{optional && <div className="text-13 leading-16 text-gray-500">(선택)</div>}
</div>
<input
className="w-full h-48 mt-4 rounded-8 p-12 gap-2.5 text-15 text-black leading-22 placeholder-gray-300 border border-gray-300 focus:border-black focus:outline-none"
placeholder={placeholder}
onChange={(e) => setValue(e.target.value)}
name={name}
value={value}
/>
</div>
);
};

export default Input;
21 changes: 21 additions & 0 deletions src/components/atoms/Contact/Instagram/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from "react";

const Instagram = () => {
return (
<div className="max-w-314 w-full h-184 flex flex-col justify-between items-start py-24 px-20 border border-gray-200 rounded-12 bg-white lg:px-20 sm:px-0">
<div className="text-16 leading-24 text-gray-700">
업브렐라 이용 안내 관련 및 급한 문의는
<br />
업브렐라 인스타그램 계정으로 부탁드려요!
</div>
<a
className=" bg-primary-200 rounded-8 px-20 py-12 font-semibold text-16 leading-24 text-primary-500"
href="https://www.instagram.com/direct/t/17846148278607764"
>
업브렐라 DM으로 문의하기
</a>
</div>
);
};

export default Instagram;
57 changes: 57 additions & 0 deletions src/components/atoms/Contact/TextArea/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { useRef, useEffect, useState, ChangeEvent } from "react";

export type TextAreaProps = {
label: string;
placeholder: string;
setValue: (value: string) => void;
name: string;
value: string;
};

const TextArea = ({ label, placeholder, setValue, name, value }: TextAreaProps) => {
const textareaRef = useRef<HTMLTextAreaElement>(null);
const [isWriting, setIsWriting] = useState(false);

useEffect(() => {
// 컴포넌트가 마운트될 때마다 textarea의 높이를 자동으로 설정
if (textareaRef.current) {
textareaRef.current.style.height = "auto";
textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;
}
}, []);

const handleTextareaChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
// textarea의 내용이 변경될 때마다 높이를 자동으로 조정
if (textareaRef.current) {
textareaRef.current.style.height = "auto"; // text를 추가할 때 높이 조정
textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`; // text를 지웠을 때 높이 조정
}

const { value } = event.target;
setIsWriting(Boolean(value));
setValue(event.target.value);
};

const borderColor = isWriting ? "gray-600" : "gray-300";
const textColor = isWriting ? "black" : "gray-400";

return (
<div className="flex-col p-5 mb-32">
<div className="flex items-center mb-4 text-gray-700 text-15 leading-22 font-normal">
{label}
</div>
<textarea
ref={textareaRef}
onChange={handleTextareaChange}
rows={3}
className={`w-full mt-4 rounded-8 border border-${borderColor} p-10 text-15 text-${textColor} leading-22 placeholder-gray-300 resize-none overflow-hidden focus:border-gray-600 focus:outline-none`}
placeholder={placeholder}
spellCheck={false}
name={name}
value={value}
/>
</div>
);
};

export default TextArea;
Loading

0 comments on commit f6446e7

Please sign in to comment.