Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FE] 🚀 테스트 서버 배포 #1066

Open
wants to merge 12 commits into
base: FE/test
Choose a base branch
from
Open
2 changes: 2 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@octokit/rest": "^21.0.1",
"@sentry/react": "^8.22.0",
"@sentry/webpack-plugin": "^2.21.1",
"@stomp/stompjs": "^7.0.0",
"@tanstack/react-query": "^5.51.11",
"dotenv-webpack": "^8.1.0",
"react": "^18.3.1",
Expand All @@ -27,6 +28,7 @@
"react-icons": "^5.3.0",
"react-router-dom": "^6.25.1",
"styled-components": "^6.1.12",
"ws": "^8.18.0",
"zustand": "^4.5.4"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import HowToPair from '@/components/Landing/HowToPair/HowToPair';

import useUserStore from '@/stores/userStore';

import { getMember } from '@/apis/member';
import { getIsUserLoggedIn } from '@/apis/oauth';
import { getMember } from '@/apis/http/member';
import { getIsUserLoggedIn } from '@/apis/http/oauth';

import GlobalStyles from './styles/Global.style';
import { theme } from './styles/theme';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fetcher from '@/apis/fetcher';
import fetcher from '@/apis/http/fetcher';

import { ERROR_MESSAGES } from '@/constants/message';

Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import fetcher from '@/apis/fetcher';
import type { PairRoomStatus } from '@/apis/pairRoom';
import fetcher from '@/apis/http/fetcher';
import type { PairRoomStatus } from '@/apis/http/pairRoom';

import { ERROR_MESSAGES } from '@/constants/message';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fetcher from '@/apis/fetcher';
import fetcher from '@/apis/http/fetcher';

import { ERROR_MESSAGES } from '@/constants/message';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Category } from '@/components/PairRoom/ReferenceCard/ReferenceCard.type';

import fetcher from '@/apis/fetcher';
import { Reference } from '@/apis/referenceLink';
import { Todo } from '@/apis/todo';
import fetcher from '@/apis/http/fetcher';
import { Reference } from '@/apis/http/referenceLink';
import { Todo } from '@/apis/http/todo';

import { ERROR_MESSAGES } from '@/constants/message';

Expand Down Expand Up @@ -100,7 +100,7 @@ export const updatePairRoomStatus = async ({ accessCode }: UpdatePairRoomStatusR
};

export const deletePairRoom = async ({ accessCode }: { accessCode: string }) => {
await fetcher.delete({
await fetcher.patch({
url: `${API_URL}/pair-room/${accessCode}`,
errorMessage: ERROR_MESSAGES.DELETE_PAIR_ROOM,
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fetcher from '@/apis/fetcher';
import fetcher from '@/apis/http/fetcher';

import { ERROR_MESSAGES } from '@/constants/message';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fetcher from '@/apis/fetcher';
import fetcher from '@/apis/http/fetcher';

import { ERROR_MESSAGES } from '@/constants/message';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import fetcher from '@/apis/fetcher';
import fetcher from '@/apis/http/fetcher';

const API_URL = process.env.REACT_APP_API_URL;
const SOCKET_URL = process.env.REACT_SOCKET_API_URL;

export const getConnection = (accessCode: string) => {
return new WebSocket(`${SOCKET_URL}/ws-connect?accesscode=${accessCode}`);
};

interface UpdateDurationRequest {
duration: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fetcher from '@/apis/fetcher';
import fetcher from '@/apis/http/fetcher';

import { ERROR_MESSAGES } from '@/constants/message';

Expand Down
21 changes: 21 additions & 0 deletions frontend/src/apis/websocket/todo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Client } from '@stomp/stompjs';

import { publishMessage } from '@/apis/websocket/websocket';

export const publishTodoMessage = {
add: (client: Client | null, accessCode: string, contents: string) => {
publishMessage(client, `/send/${accessCode}/todo/add`, { contents });
},
updateContents: (client: Client | null, accessCode: string, todoId: number, contents: string) => {
publishMessage(client, `/send/${accessCode}/todo/update/${todoId}/contents`, { contents });
},
updateOrder: (client: Client | null, accessCode: string, todoId: number, order: number) => {
publishMessage(client, `/send/${accessCode}/todo/update/${todoId}/order`, { order });
},
updateChecked: (client: Client | null, accessCode: string, todoId: number) => {
publishMessage(client, `/send/${accessCode}/todo/update/${todoId}/checked`);
},
delete: (client: Client | null, accessCode: string, todoId: number) => {
publishMessage(client, `/send/${accessCode}/todo/delete/${todoId}`);
},
};
31 changes: 31 additions & 0 deletions frontend/src/apis/websocket/websocket.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Client, Message } from '@stomp/stompjs';

const SOCKET_URL = process.env.REACT_SOCKET_API_URL;

export const getConnection = () => {
return new Client({ brokerURL: `${SOCKET_URL}/ws-connect` });
};

export const subscribeTopic = <T>(client: Client | null, destination: string, handler: (body: T) => void) => {
if (!client?.connected) {
console.error('웹소켓 연결에 실패했습니다.');
return;
}

client.subscribe(destination, (message: Message) => {
const body: T = JSON.parse(message.body);
handler(body);
});
};

export const publishMessage = (client: Client | null, destination: string, contents?: object) => {
if (!client?.connected) {
console.error('[ERROR] 서버와 통신에 실패했습니다.');
return;
}

client.publish({
destination: destination,
body: JSON.stringify(contents),
});
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Link } from 'react-router-dom';

import type { Reference } from '@/apis/referenceLink';
import type { Reference } from '@/apis/http/referenceLink';

import * as S from './ReferenceList.styles';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState } from 'react';

import { Todo } from '@/apis/todo';
import { Todo } from '@/apis/http/todo';

import useCopyClipBoard from '@/hooks/_common/useCopyClipboard';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type Story = StoryObj<typeof PairRoomCreateModal>;

export const Default: Story = {
render: () => {
return <PairRoomCreateModal isOpen={true} closeModal={() => console.log()} />;
return <PairRoomCreateModal isOpen={true} closeModal={() => alert('닫기')} />;
},
args: {
isOpen: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Modal } from '@/components/_common/Modal';

import useToastStore from '@/stores/toastStore';

import { getPairRoomExists } from '@/apis/pairRoom';
import { getPairRoomExists } from '@/apis/http/pairRoom';

import useClickEnterKey from '@/hooks/_common/customEvent/useClickEnterKey';
import useInput from '@/hooks/_common/useInput';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Link } from 'react-router-dom';
import { FaTrashAlt } from 'react-icons/fa';
import styled, { keyframes, css } from 'styled-components';

import type { PairRoomStatus } from '@/apis/pairRoom';
import type { PairRoomStatus } from '@/apis/http/pairRoom';

import { Z_INDEX } from '@/constants/style';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { IoIosArrowForward } from 'react-icons/io';
import ConfirmModal from '@/components/_common/ConfirmModal/ConfirmModal';
import Spinner from '@/components/_common/Spinner/Spinner';

import type { PairRoomStatus } from '@/apis/pairRoom';
import type { PairRoomStatus } from '@/apis/http/pairRoom';

import useModal from '@/hooks/_common/useModal';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,5 @@ export default meta;
type Story = StoryObj<typeof ReferenceCard>;

export const Default: Story = {
render: () => (
<ReferenceCard accessCode="1234" isOpen={true} toggleIsOpen={() => {}} references={[]} categories={[]} />
),
render: () => <ReferenceCard isOpen={true} toggleIsOpen={() => {}} references={[]} categories={[]} />,
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import Header from '@/components/PairRoom/ReferenceCard/Header/Header';
import { Category } from '@/components/PairRoom/ReferenceCard/ReferenceCard.type';
import ReferenceList from '@/components/PairRoom/ReferenceCard/ReferenceList/ReferenceList';

import { Reference } from '@/apis/referenceLink';
import useSocketStore from '@/stores/socketStore';

import { Reference } from '@/apis/http/referenceLink';

import useModal from '@/hooks/_common/useModal';

Expand All @@ -18,14 +20,15 @@ import { findValueById } from '@/utils/findOption';
import * as S from './ReferenceCard.styles';

interface ReferenceCardProps {
accessCode: string;
isOpen: boolean;
toggleIsOpen: () => void;
references: Reference[];
categories: Category[];
}

const ReferenceCard = ({ accessCode, isOpen, toggleIsOpen, references, categories }: ReferenceCardProps) => {
const ReferenceCard = ({ isOpen, toggleIsOpen, references, categories }: ReferenceCardProps) => {
const { accessCode } = useSocketStore();

const [selectedCategoryId, setSelectedCategoryId] = useState(DEFAULT_CATEGORY_ID);

const { isModalOpen, openModal, closeModal } = useModal();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Link } from 'react-router-dom';

import type { Reference } from '@/apis/referenceLink';
import type { Reference } from '@/apis/http/referenceLink';

import useReferencesMutation from '@/queries/PairRoom/useReferencesMutation';

Expand Down
21 changes: 12 additions & 9 deletions frontend/src/components/PairRoom/TimerCard/TimerCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { FaPause, FaPlay } from 'react-icons/fa6';
import IconButton from '@/components/_common/IconButton/IconButton';
import { PairRoomCard } from '@/components/PairRoom/PairRoomCard';
import TimerEditPanel from '@/components/PairRoom/TimerCard/TimerEditPanel/TimerEditPanel';
import TimerPip from '@/components/PairRoom/TimerPip/TimerPip';

import useTimer from '@/hooks/PairRoom/useTimer';
import useTitleTime from '@/hooks/PairRoom/useTitleTime';
Expand All @@ -16,19 +17,13 @@ import { theme } from '@/styles/theme';
import * as S from './TimerCard.styles';

interface TimerCardProps {
accessCode: string;
defaultTime: number;
defaultTimeleft: number;
defaultTimeLeft: number;
onTimerStop: () => void;
}

const TimerCard = ({ accessCode, defaultTime, defaultTimeleft, onTimerStop }: TimerCardProps) => {
const { timeLeft, isActive, handleStart, handlePause } = useTimer(
accessCode,
defaultTime,
defaultTimeleft,
onTimerStop,
);
const TimerCard = ({ defaultTime, defaultTimeLeft, onTimerStop }: TimerCardProps) => {
const { timeLeft, isActive, handleStart, handlePause } = useTimer(defaultTime, defaultTimeLeft, onTimerStop);

const timeLeftRef = useRef(timeLeft);
timeLeftRef.current = timeLeft;
Expand All @@ -39,6 +34,14 @@ const TimerCard = ({ accessCode, defaultTime, defaultTimeleft, onTimerStop }: Ti
return (
<PairRoomCard>
<S.Layout aria-label="타이머">
<TimerPip
isActive={isActive}
minutes={minutes}
seconds={seconds}
progress={(timeLeft / defaultTime) * 100}
handleStart={handleStart}
handlePause={handlePause}
/>
<S.ProgressBar
$progress={(timeLeft / defaultTime) * 100}
role="timer"
Expand Down
94 changes: 94 additions & 0 deletions frontend/src/components/PairRoom/TimerPip/TimerPip.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
export const styles = `
@import url('https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css');

body {
margin: 0;
display: flex;
justify-content: center;
align-items: center;
background: #F6F3F3;
height: 100%;
width: 100%;
font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
}

.timer {
display: flex;
align-items: center;
gap: 8px;
font-size: 24px;
width: 100%;
height: 100%;
}

.timer-container {
width:4rem;
display:flex;
justify-content: center;
align-items: center;
}

.timer-text {
font-weight: regular;
font-size: 55px;
}

.layout {
display: flex;
align-items: center;
flex-direction: column;
width: 100%;
height: 11rem;
justify-content: center;
position:relative;
}

.container {
display: flex;
gap:0.3rem;
}

.progress-bar {
width: 100%;
height: 8px;
background: #e4e4e4;
border-radius: 6px;
overflow: hidden;
margin: 8px 0;
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
}

.progress-bar-fill {
height: 100%;
background: linear-gradient(to right, #00E0C8, #00C2AD);
border-radius: 4px;
transition: width 0.3s ease-out;
box-shadow: 0 0 8px rgba(0, 224, 200, 0.5);
}

button{
background-color: #F7EAD3;
border-radius: 0.5rem;
border: none;
width: 2.3rem;
height: 2.1rem;
display: flex;
justify-content: center;
align-items: center;
cursor:pointer;
}
.button-container{
display: flex;
align-items: center;
justify-content:center;
gap: 4px;
margin-top:1rem;
}

button:hover{
opacity: 1.2;
background-color: #f3e2c6;
transition: all 0.2s;
}

`;
Loading
Loading