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

Refactor/api provider #149

Merged
merged 6 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Outlet } from 'react-router-dom';
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';

import { AuthProvider } from './contexts/AuthContext';
import { AuthProvider } from './contexts/AuthProvider';
import { ThemeProvider } from './contexts/ThemeProvider';
import ThemeComponent from './components/temp/ThemedComponent';

Expand Down
16 changes: 0 additions & 16 deletions client/src/apis/Auth.ts

This file was deleted.

6 changes: 6 additions & 0 deletions client/src/apis/apiClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import axios, { AxiosInstance } from 'axios';

export const apiClient: AxiosInstance = axios.create({
baseURL: import.meta.env.VITE_BASE_URL as string,
withCredentials: true,
});
22 changes: 12 additions & 10 deletions client/src/apis/createRoom.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import axios from 'axios';
import { AxiosError } from 'axios';
import { RoomCreateType } from '../types/RoomCreateType';

const VITE_BASE_URL = import.meta.env.VITE_BASE_URL as string;
import { apiClient } from './apiClient';

export async function createRoom(): Promise<RoomCreateType | undefined> {
const response = await axios.post(
`${VITE_BASE_URL}/room`,
{},
{ withCredentials: true },
);

return response.data;
try {
const { data } = await apiClient.post('/room', {});
return data;
} catch (error) {
if (error instanceof AxiosError) {
// TODO: 이거 session로직 수정되면 여기도 고쳐야 됨
// 세션에서 현재 유저가 방에 참가중인지, 어떤 방에 참가중인지 정보를 받아 올 수 있어야 함
alert(error.response!.data.message);
}
}
}
10 changes: 6 additions & 4 deletions client/src/apis/exitRoom.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import axios from 'axios';

const VITE_BASE_URL = import.meta.env.VITE_BASE_URL as string;
import { apiClient } from './apiClient';

export async function exitRoom() {
await axios.post(`${VITE_BASE_URL}/room/exit`, {}, { withCredentials: true });
try {
await apiClient.post('/room/exit');
} catch (error) {
console.log(error);
}
}
11 changes: 11 additions & 0 deletions client/src/apis/getSession.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { CreateUser } from '../types/CreateUserType';
import { apiClient } from './apiClient';

export async function getSession(): Promise<CreateUser | undefined> {
try {
const { data }: { data: CreateUser } = await apiClient.get('/session');
return data;
} catch (error) {
console.log(error);
}
}
16 changes: 6 additions & 10 deletions client/src/apis/joinRoom.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import axios from 'axios';

const VITE_BASE_URL = import.meta.env.VITE_BASE_URL as string;
import { apiClient } from './apiClient';

export async function joinRoom(roomCode: string) {
await axios.post(
`${VITE_BASE_URL}/room/join`,
{ code: roomCode },
{
withCredentials: true,
},
);
try {
await apiClient.post('/room/join', { code: roomCode });
} catch (error) {
console.log(error);
}
}
9 changes: 9 additions & 0 deletions client/src/apis/logout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { apiClient } from './apiClient';

export async function logout() {
try {
await apiClient.get('/auth/logout');
} catch (error) {
console.log(error);
}
}
14 changes: 14 additions & 0 deletions client/src/apis/mockLogin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { apiClient } from './apiClient';

type mockUser = {
username: string;
password: string;
};

export async function mockLoginApi(mockUser: mockUser) {
try {
return await apiClient.post('/auth/mock', mockUser);
} catch (error) {
console.log(error);
}
}
25 changes: 12 additions & 13 deletions client/src/apis/searchProblem.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import axios from 'axios';
import { ProblemResponse } from '../types/Problem';

export async function searchProblem(searchKeyword: string): Promise<ProblemResponse[]> {
const VITE_BASE_URL = import.meta.env.VITE_BASE_URL as string;
import { apiClient } from './apiClient';

if(!searchKeyword) return Promise.resolve([]);
export async function searchProblem(
searchKeyword: string,
): Promise<ProblemResponse[]> {
if (!searchKeyword) return Promise.resolve([]);

return await axios
.get(`${VITE_BASE_URL}/problem`, {
try {
const { data } = await apiClient.get('/problem', {
params: {
searchKeyword,
},
})
.then((res) => {
return res.data || [];
})
.catch((err) => {
console.log(err);
return [];
});
return data;
} catch (error) {
console.log(error);
return [];
}
}
4 changes: 2 additions & 2 deletions client/src/components/Chat.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { FaArrowRight } from 'react-icons/fa6';
import Message from './Message';
import { useAuthContext } from '../contexts/AuthProvider';
import { ChatEvent, MessageInterface } from '../types/Message';
import { useAuthContext } from '../contexts/AuthContext';
import { Socket } from 'socket.io-client';

// TODO: userColor -> 서버에서 설정
Expand Down Expand Up @@ -36,7 +36,7 @@ export default function Chat({
username: user?.username || 'Anonymous',
body: inputText,
chatEvent: ChatEvent.Message,
color: 'text-purple', // TODO: 서버에서 설정
color: 'text-purple', // TODO: 클라에서 랜덤 설정
};

socket.emit('chat-message', newChatMessage);
Expand Down
4 changes: 2 additions & 2 deletions client/src/components/Profile.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useAuthContext } from '../contexts/AuthContext';
import { useAuthContext } from '../contexts/AuthProvider';

export default function Profile() {
const { user } = useAuthContext();
Expand All @@ -11,7 +11,7 @@ export default function Profile() {
src={user!.avatarUrl}
alt="프로필 이미지"
/>
<p className="text-text_default text-lg font-semibold">
<p className="text-lg font-semibold text-text_default">
{user!.username}
</p>
</div>
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/buttons/LogoutButton.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useAuthUpdateContext } from '../../contexts/AuthContext';
import { useAuthUpdateContext } from '../../contexts/AuthProvider';

export default function LogoutButton() {
const { onLogout } = useAuthUpdateContext();
Expand Down
11 changes: 5 additions & 6 deletions client/src/components/buttons/RoomCreateButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ export default function RoomCreateButton() {
try {
const roomInfo: RoomCreateType | undefined = await createRoom();
if (roomInfo === undefined) {
setTimeout(() => {
console.log(roomInfo);
alert('방 생성에 실패했습니다.');
setIsLoading(false);
}, 1000);

// setTimeout(() => {
// alert('방 생성에 실패했습니다.');
//
// }, 1000);
setIsLoading(false);
return;
}
const roomCode = roomInfo.code;
Expand Down
19 changes: 8 additions & 11 deletions client/src/components/temp/MockLogin.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import axios from 'axios';
import { mockLoginApi } from '../../apis/mockLogin';

export default function MockLogin() {
const baseURL = import.meta.env.VITE_BASE_URL;

async function mockLogin({ id }: { id: string }) {
const mockUser = {
username: `mock${id}`,
password: `mock${id}`,
};
const response = await axios.post(`${baseURL}/auth/mock`, mockUser, {
withCredentials: true,
});
if (response.status === 201) {
const response = await mockLoginApi(mockUser);
console.log(response);
if (response?.status === 201) {
console.log(response.data);
// AuthProvider의 useEffect가 실행되지 않아서 새로고침을 해줘야 함
// 원래라면 AuthProvider에 따로 메서드를 만들어줘야하는게 맞는데 mock이라서 그냥 새로고침으로 대체
Expand All @@ -23,31 +20,31 @@ export default function MockLogin() {
<div className="flex gap-2">
<button
id="1"
className="text-text_default bg-default_black my-2 flex items-center gap-2 rounded-lg px-4 py-2.5 text-sm hover:hover:bg-opacity-50"
className="my-2 flex items-center gap-2 rounded-lg bg-default_black px-4 py-2.5 text-sm text-text_default hover:hover:bg-opacity-50"
onClick={() => {
mockLogin({ id: '1' });
}}>
Mock 1
</button>
<button
id="2"
className="text-text_default bg-default_black my-2 flex items-center gap-2 rounded-lg px-4 py-2.5 text-sm hover:hover:bg-opacity-50"
className="my-2 flex items-center gap-2 rounded-lg bg-default_black px-4 py-2.5 text-sm text-text_default hover:hover:bg-opacity-50"
onClick={() => {
mockLogin({ id: '2' });
}}>
Mock 2
</button>
<button
id="3"
className="text-text_default bg-default_black my-2 flex items-center gap-2 rounded-lg px-4 py-2.5 text-sm hover:hover:bg-opacity-50"
className="my-2 flex items-center gap-2 rounded-lg bg-default_black px-4 py-2.5 text-sm text-text_default hover:hover:bg-opacity-50"
onClick={() => {
mockLogin({ id: '3' });
}}>
Mock 3
</button>
<button
id="4"
className="text-text_default bg-default_black my-2 flex items-center gap-2 rounded-lg px-4 py-2.5 text-sm hover:hover:bg-opacity-50"
className="my-2 flex items-center gap-2 rounded-lg bg-default_black px-4 py-2.5 text-sm text-text_default hover:hover:bg-opacity-50"
onClick={() => {
mockLogin({ id: '4' });
}}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { useNavigate } from 'react-router-dom';
import { createContext, useContext, useEffect, useState } from 'react';
import {
ReactNode,
createContext,
useContext,
useEffect,
useState,
} from 'react';
import { CreateUser } from '../types/CreateUserType';
import { getSession, logout } from '../apis/Auth';
import { logout } from '../apis/logout';
import { getSession } from '../apis/getSession';

interface AuthContextType {
user: CreateUser | null;
Expand All @@ -11,39 +18,30 @@ interface AuthUpdateType {
onLogout: () => void;
}

interface AuthProviderProps {
children: ReactNode;
}

const AuthContext = createContext<AuthContextType>({} as AuthContextType);
const AuthUpdateContext = createContext<AuthUpdateType>({} as AuthUpdateType);

export const AuthProvider = ({ children }: { children: JSX.Element }) => {
export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
const navigate = useNavigate();

const [user, setUser] = useState<CreateUser | null>(null);

const onLogout = () => {
try {
logout();
setUser(null);
navigate('/');
} catch (err) {
console.error(err);
throw err;
}
logout();
setUser(null);
navigate('/');
};

useEffect(() => {
(async () => {
try {
const user = await getSession();

if (user) {
setUser(user);
} else {
setUser(null);
}
} catch (error) {
console.error(error);
getSession().then((data) => {
if (data) {
setUser(data);
}
})();
});
}, []);

return (
Expand Down
7 changes: 3 additions & 4 deletions client/src/contexts/ThemeProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ type Theme =
| 'atom-one-light'
| 'github-dark'
| 'github-light';

type ThemeContextType = {
theme: Theme;
toggleTheme: () => void;
};

const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
const ThemeContext = createContext<ThemeContextType>({} as ThemeContextType);

interface ThemeProviderProps {
children: ReactNode;
Expand All @@ -27,17 +28,15 @@ interface ThemeProviderProps {
const localStorageKey = 'theme';

export const ThemeProvider: React.FC<ThemeProviderProps> = ({ children }) => {
// Retrieve theme from localStorage or use 'default' as the default value
const storedTheme = localStorage.getItem(localStorageKey) as Theme | null;
const [theme, setTheme] = useState<Theme>(storedTheme || 'atom-one-dark');

useEffect(() => {
// Update data-theme attribute when the theme changes
document.documentElement.setAttribute('data-theme', theme);
// Save the theme to localStorage
localStorage.setItem(localStorageKey, theme);
}, [theme]);

// TODO: change setting function
const toggleTheme = () => {
setTheme((prevTheme) => {
switch (prevTheme) {
Expand Down
2 changes: 1 addition & 1 deletion client/src/pages/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useNavigate } from 'react-router-dom';
import { useAuthContext } from '../contexts/AuthContext';
import { useAuthContext } from '../contexts/AuthProvider';
import GithubLoginButton from '../components/buttons/GithubLoginButton';
import { useEffect } from 'react';
import MockLogin from '../components/temp/MockLogin';
Expand Down
Loading