Skip to content

Commit 0fb4ed0

Browse files
authored
Merge pull request #157 from MBTips/dev
9차 배포 Test (Dev -> Main)
2 parents 23cf871 + 1a2d7f8 commit 0fb4ed0

14 files changed

Lines changed: 320 additions & 105 deletions

File tree

.github/workflows/ci.yml

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ name: 빌드 자동화
33
on:
44
push:
55
branches:
6-
- main
7-
- feat/cicd
6+
- dev
87

98
jobs:
109
build:
@@ -14,39 +13,13 @@ jobs:
1413
- name: Checkout code
1514
uses: actions/checkout@v2
1615

17-
- name: Set up Node.js (언어 환경)
16+
- name: Set up Node.js (또는 다른 언어 환경)
1817
uses: actions/setup-node@v2
1918
with:
2019
node-version: "20"
2120

22-
- name: Create .env.production file
23-
run: |
24-
echo "MODE=production" > .env.production
25-
echo "VITE_GA_MEASUREMENT_ID=${{ secrets.VITE_GA_MEASUREMENT_ID }}" >> .env.production
26-
2721
- name: Install dependencies
28-
run: npm ci
22+
run: npm install
2923

3024
- name: Run build
31-
env:
32-
NODE_ENV: production
33-
run: npm run build -- --mode production
34-
35-
- name: Docker build & push
36-
run: |
37-
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
38-
docker build -t ${{ secrets.DOCKER_USERNAME }}/embitips_front .
39-
docker push ${{ secrets.DOCKER_USERNAME }}/embitips_front
40-
41-
- name: Deploy to GCP
42-
uses: appleboy/ssh-action@master
43-
with:
44-
host: ${{ secrets.HOST_PROD }}
45-
username: ${{ secrets.USERNAME }}
46-
key: ${{ secrets.PRIVATE_KEY }}
47-
script: |
48-
sudo docker stop embitips_front || true
49-
sudo docker rm embitips_front || true
50-
sudo docker pull ${{ secrets.DOCKER_USERNAME }}/embitips_front
51-
sudo docker run -d -p 3000:3000 --name embitips_front ${{ secrets.DOCKER_USERNAME }}/embitips_front
52-
sudo docker image prune -f
25+
run: npm run build

.github/workflows/cicd.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: 빌드 자동화
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- feat/cicd
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout code
15+
uses: actions/checkout@v2
16+
17+
- name: Set up Node.js (언어 환경)
18+
uses: actions/setup-node@v2
19+
with:
20+
node-version: "20"
21+
22+
- name: Install dependencies
23+
run: |
24+
npm install
25+
npm install tailwindcss@latest postcss@latest autoprefixer@latest
26+
npm install --save-dev @types/node
27+
28+
- name: Create .env file # env 파일 생성 단계 추가
29+
run: |
30+
echo "VITE_GA_MEASUREMENT_ID=${{ secrets.VITE_GA_MEASUREMENT_ID }}" > .env
31+
32+
- name: Run build
33+
run: npm run build # 프로젝트에 맞는 빌드 명령어
34+
35+
- name: Docker build & push
36+
run: |
37+
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
38+
docker build -t ${{ secrets.DOCKER_USERNAME }}/embitips_front .
39+
docker push ${{ secrets.DOCKER_USERNAME }}/embitips_front
40+
41+
- name: Deploy to GCP
42+
uses: appleboy/ssh-action@master
43+
with:
44+
host: ${{ secrets.HOST_PROD }}
45+
username: ${{ secrets.USERNAME }}
46+
key: ${{ secrets.PRIVATE_KEY }}
47+
script: |
48+
sudo docker stop embitips_front || true
49+
sudo docker rm embitips_front || true
50+
sudo docker pull ${{ secrets.DOCKER_USERNAME }}/embitips_front
51+
sudo docker run -d -p 3000:3000 --name embitips_front ${{ secrets.DOCKER_USERNAME }}/embitips_front
52+
sudo docker image prune -f

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"build": "vite build --mode production",
99
"lint": "eslint .",
1010
"preview": "vite preview",
11-
"start": "vite --port 3000"
11+
"start": "vite --port 3000 --mode production"
1212
},
1313
"dependencies": {
1414
"@tailwindcss/vite": "^4.0.3",

src/App.tsx

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import ChatTips from "@/pages/ChatTips";
1313
import ChatTemporature from "@/pages/ChatTemporature";
1414
import Content from "@/pages/Content";
1515
import Login from "@/pages/Login";
16+
import MyInfo from "@/pages/MyInfo";
1617
import KaKaoLogin from "@/pages/KaKaoLogin";
1718
import MbtiTestIntro from "@/pages/MbtiTestIntro";
1819
import MbtiTestQuestions from "@/pages/MbtiTestQuestions";
@@ -22,24 +23,42 @@ import { initGA, trackPageView } from "@/libs/analytics";
2223

2324
const PageTracker = () => {
2425
const location = useLocation();
26+
const { pathname, state } = location;
2527

2628
const trackedPaths = [
27-
{ path: "/", label: "home" },
28-
{ path: "/login", label: "login" },
29-
{ path: "/contents" }
29+
{ path: "/", page: "홈", element: "" },
30+
{ path: "/login", page: "로그인/회원가입", element: "로그인" },
31+
{ path: "/contents", page: "일반콘텐츠", element: "" },
32+
{ path: "/my-info", page: "내 정보", element: "" },
33+
{ path: "/chat", page: "채팅방", element: "" },
34+
{ path: "/select-info", page: "빠른 대화 설정", element: "" },
35+
{ path: "/select-info", page: "친구 저장", element: "대화 시작하기" }
3036
];
3137

3238
useEffect(() => {
33-
const { pathname } = location;
39+
const trackedContentPaths = ["/contents/1", "/contents/2"];
3440

35-
trackedPaths.forEach(({ path, label }) => {
36-
if (path === "/contents" && pathname.startsWith(path)) {
37-
trackPageView(label || pathname);
38-
} else if (pathname === path) {
39-
trackPageView(label || pathname);
41+
trackedPaths.forEach(({ path, page, element }) => {
42+
// 콘텐츠 상세 페이지 (일반 콘텐츠만 추적)
43+
if (trackedContentPaths.includes(pathname)) {
44+
if (path === "/contents") {
45+
trackPageView(path, { page, element });
46+
}
47+
}
48+
// select-info 페이지에서 state로 분기
49+
else if (pathname === "/select-info" && path === pathname) {
50+
if (state === "fastFriend" && page === "빠른 대화 설정") {
51+
trackPageView(path, { page, element });
52+
} else if (state === "virtualFriend" && page === "친구 저장") {
53+
trackPageView(path, { page, element });
54+
}
55+
}
56+
// 나머지 일반 path
57+
else if (pathname === path && path !== "/select-info") {
58+
trackPageView(path, { page, element });
4059
}
4160
});
42-
}, [location.pathname]);
61+
}, [location.pathname, location.state]);
4362

4463
return null;
4564
};
@@ -63,6 +82,7 @@ const App = () => {
6382
<Route path="/chat-temporature" element={<ChatTemporature />} />
6483
<Route path="/contents/:id" element={<Content />} />
6584
<Route path="/login" element={<Login />} />
85+
<Route path="/my-info" element={<MyInfo />} />
6686
<Route path="/kakao-login" element={<KaKaoLogin />} />
6787
<Route path="/mbti-test" element={<MbtiTestIntro />} />
6888
<Route path="/mbti-test/:n" element={<MbtiTestQuestions />} />

src/components/ChatAction.tsx

Lines changed: 0 additions & 28 deletions
This file was deleted.

src/components/ChatActionBar.tsx

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { ChangeEvent, KeyboardEvent } from "react";
2+
import ToggleChatTipsButton from "@/components/button/ToggleChatTipsButton";
3+
import MessageInput from "@/components/input/MessageInput";
4+
5+
interface ChatActionProps {
6+
isOpen: boolean;
7+
setIsOpen: (open: boolean) => void;
8+
value: string;
9+
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
10+
onKeyUp: (e: KeyboardEvent<HTMLInputElement>) => void;
11+
onSend: () => void;
12+
}
13+
14+
const ChatActionBar = ({
15+
isOpen,
16+
setIsOpen,
17+
value,
18+
onChange,
19+
onKeyUp,
20+
onSend
21+
}: ChatActionProps) => {
22+
return (
23+
<div className="flex h-[68px] w-full items-center justify-center border-t border-gray-100 bg-white">
24+
<ToggleChatTipsButton isOpen={isOpen} setIsOpen={setIsOpen} />
25+
<MessageInput value={value} onChange={onChange} onKeyUp={onKeyUp} />
26+
<img
27+
className={`ml-4 ${value ? "cursor-pointer" : "cursor-not-allowed"}`}
28+
onClick={onSend}
29+
src={value ? "/icon/submit_action.svg" : "/icon/submit_disabled.svg"}
30+
alt="메시지 제출"
31+
width={40}
32+
height={40}
33+
/>
34+
</div>
35+
);
36+
};
37+
38+
export default ChatActionBar;

src/components/ChatMessage.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ const ChatMessage = ({ message, myMessage }: ChatMessageProps) => {
1111
: "rounded-tl-none border border-gray-100";
1212

1313
return (
14-
<div className="flex w-full justify-center items-center mb-2">
14+
<div className="mb-[6px]">
1515
<div
16-
className={`max-w-xs px-2.5 py-3 rounded-[12px] ${borderStyle} ${backgroundColor} ${textColor}`}
16+
className={`max-w-xs rounded-[12px] px-2.5 py-3 ${borderStyle} ${backgroundColor} ${textColor}`}
1717
style={{
1818
fontWeight: 500,
1919
fontSize: "16px",

src/components/IntroGuide.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
const IntroGuide = () => {
22
return (
3-
<div className="bg-white p-5 border border-primary-light rounded-xl">
4-
<p className="font-light text-lg whitespace-pre-line">
3+
<div className="rounded-xl border border-primary-light bg-white p-5 text-black">
4+
<p className="text-md font-light whitespace-pre-line">
55
{`MBTI 대화에 참여하셨군요!
66
대화 상황에 대해 구체적으로
77
말씀해주시면,더 좋은 답변을 드릴 수 있어요 :)`}
88
</p>
9-
<strong className="block mt-2 font-medium text-lg">
9+
<p className="mt-2 block text-md font-medium">
1010
언제, 어디서, 어떤 상황인지 자유롭게 알려주세요
11-
</strong>
11+
</p>
1212
</div>
1313
);
1414
};

src/components/input/MessageInput.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1-
import { ChangeEvent } from "react";
1+
import { ChangeEvent, KeyboardEvent } from "react";
22

33
interface MessageInputProps {
44
value: string;
55
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
6+
onKeyUp: (e: KeyboardEvent<HTMLInputElement>) => void;
67
}
78

8-
const MessageInput = ({ value, onChange }: MessageInputProps) => {
9+
const MessageInput = ({ value, onChange, onKeyUp }: MessageInputProps) => {
910
return (
1011
<input
11-
className="bg-gray-50 ml-2.5 px-4 py-2.5 rounded-[40px] w-[257px] h-[44px] font-medium text-2lg text-gray-900 placeholder:text-gray-600"
12-
placeholder="메시지를 입력해주세요."
12+
type="text"
13+
className="ml-2.5 flex h-[44px] w-[242px] justify-center rounded-[40px] bg-gray-50 py-2.5 pl-4 text-lg leading-[24px] font-medium text-gray-900 placeholder:text-gray-600 md:w-[257px] lg:w-[382px]"
14+
placeholder="메시지를 입력해주세요"
1315
value={value}
1416
onChange={onChange}
17+
onKeyUp={onKeyUp}
1518
/>
1619
);
1720
};

src/libs/analytics.ts

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,28 @@ const GA_MEASUREMENT_ID = import.meta.env.VITE_GA_MEASUREMENT_ID || "";
44

55
const isProduction = import.meta.env.MODE === "production";
66

7-
const initGA = () => {
8-
console.log("import.meta.env.MODE", import.meta.env.MODE);
7+
export const initGA = () => {
98
console.log("isProduction", isProduction);
109
console.log("ID", GA_MEASUREMENT_ID);
1110
if (isProduction && GA_MEASUREMENT_ID) {
11+
console.log("initGA");
1212
ReactGA.initialize(GA_MEASUREMENT_ID);
1313
}
1414
};
1515

16-
const trackPageView = (path: string) => {
17-
console.log("trackPageView 1");
16+
export const trackPageView = (url: string, params?: Record<string, string>) => {
1817
if (isProduction && GA_MEASUREMENT_ID) {
19-
console.log("trackPageView 2");
20-
ReactGA.send({ hitType: "pageview", page: path });
18+
console.log("trackPageView");
19+
ReactGA.gtag("event", "page_view", {
20+
page_path: url,
21+
...params
22+
});
2123
}
2224
};
2325

24-
const trackEvent = (category: string, action: string, label?: string) => {
26+
export const trackEvent = (name: string, params?: Record<string, string>) => {
2527
if (isProduction && GA_MEASUREMENT_ID) {
26-
ReactGA.event({
27-
category,
28-
action,
29-
label
30-
});
28+
console.log("trackEvent");
29+
ReactGA.event(name, params);
3130
}
3231
};
33-
34-
export { initGA, trackPageView, trackEvent };

0 commit comments

Comments
 (0)