+
-
- {[...Array(2)].map((_, i) => (
-
- {i < lives ? (
-
- ) : (
-
- )}
-
- ))}
-
+
-
- {' '}
- {/* 반응형 클래스 추가 */}
-
- {/* 사이렌 애니메이션 요소 */}
-
- {displayMessage}
-
- {canvasId && (
-
- )}
-
-
+ {isOpen && (
+
+
+
+
+ {displayMessage}
+
+
+
+ {canvasId && (
+
+ )}
+
+
+
+ )}
>
);
};
diff --git a/src/hooks/useViewport.ts b/src/hooks/useViewport.ts
new file mode 100644
index 0000000..fe334d8
--- /dev/null
+++ b/src/hooks/useViewport.ts
@@ -0,0 +1,13 @@
+import { useState, useEffect } from 'react';
+
+export const useViewport = () => {
+ const [width, setWidth] = useState(window.innerWidth);
+
+ useEffect(() => {
+ const handleWindowResize = () => setWidth(window.innerWidth);
+ window.addEventListener('resize', handleWindowResize);
+ return () => window.removeEventListener('resize', handleWindowResize);
+ }, []);
+
+ return { width };
+};
diff --git a/src/services/authService.ts b/src/services/authService.ts
index 91d5ee0..49e923d 100644
--- a/src/services/authService.ts
+++ b/src/services/authService.ts
@@ -113,3 +113,29 @@ export const authService = {
}
},
};
+
+// --- 비회원 로그인 ---
+export const guestLogin = async (nickname: string) => {
+ try {
+ const response = await apiClient.post('/user/signup', {
+ userName: nickname,
+ });
+ console.log(response);
+ const authHeader = response.headers['authorization'];
+ const accessToken = authHeader?.split(' ')[1];
+
+ // const accessToken = response.data.access_token;
+
+ const decodedToken = jwtDecode
(accessToken);
+ const user = {
+ userId: decodedToken.sub.userId,
+ nickname: decodedToken.sub.nickName,
+ };
+
+ useAuthStore.getState().setAuth(accessToken, user);
+ toast.success(`${nickname}님 환영합니다!`);
+ } catch (error) {
+ console.error('Login failed', error);
+ toast.error('로그인에 실패했습니다.');
+ }
+};
diff --git a/src/utils/getRandomName.ts b/src/utils/getRandomName.ts
new file mode 100644
index 0000000..0721859
--- /dev/null
+++ b/src/utils/getRandomName.ts
@@ -0,0 +1,57 @@
+export const generateRandomNickname = (): string => {
+ const names = [
+ 'JavaScript',
+ 'Python',
+ 'Java',
+ 'C++',
+ 'C#',
+ 'Ruby',
+ 'Go',
+ 'Swift',
+ 'Kotlin',
+ 'TypeScript',
+ 'PHP',
+ 'Rust',
+ 'Scala',
+ 'Perl',
+ 'Haskell',
+ 'Lua',
+ 'Dart',
+ 'SQL',
+ 'MATLAB',
+ 'Assembly',
+ 'Flutter',
+ 'React',
+ 'Nest',
+ 'Next',
+ 'Zustand',
+ 'nodeJS',
+ 'Umlang',
+ 'R',
+ 'HTML',
+ 'CSS',
+ 'Scratch',
+ ];
+
+ const getRandomItem = (arr: string[]): string =>
+ arr[Math.floor(Math.random() * arr.length)];
+
+ const generateRandomNumber = (min: number, max: number): string =>
+ Math.floor(min + Math.random() * (max - min + 1)).toString();
+
+ const selectNamePart = (): string => getRandomItem(names);
+
+ const namePart = selectNamePart();
+
+ const remainingLength = Math.max(0, 8 - namePart.length);
+
+ const numberPart =
+ remainingLength > 0
+ ? generateRandomNumber(
+ Math.pow(10, remainingLength - 1),
+ Math.pow(10, remainingLength) - 1
+ )
+ : '';
+
+ return `${namePart}${numberPart}`;
+};
diff --git a/tailwind.config.js b/tailwind.config.js
new file mode 100644
index 0000000..29d7665
--- /dev/null
+++ b/tailwind.config.js
@@ -0,0 +1,15 @@
+/** @type {import('tailwindcss').Config} */
+export default {
+ content: [
+ "./index.html",
+ "./src/**/*.{js,ts,jsx,tsx}",
+ ],
+ theme: {
+ extend: {
+ fontFamily: {
+ 'press-start': ['"Press Start 2P"', 'cursive'],
+ },
+ },
+ },
+ plugins: [],
+}