From 6f36ad5f1c6f62a1aa0a006887d00aee08514aca Mon Sep 17 00:00:00 2001 From: valofosho Date: Wed, 21 Aug 2024 18:21:16 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20Welcome.js=20&=20Welcome.css=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [#77] --- Re-Frontend/src/components/Welcome.js | 119 +++++++++++++++++++++++ Re-Frontend/src/css/Welcome.css | 132 ++++++++++++++++++++++++++ 2 files changed, 251 insertions(+) create mode 100644 Re-Frontend/src/components/Welcome.js create mode 100644 Re-Frontend/src/css/Welcome.css diff --git a/Re-Frontend/src/components/Welcome.js b/Re-Frontend/src/components/Welcome.js new file mode 100644 index 00000000..6986a736 --- /dev/null +++ b/Re-Frontend/src/components/Welcome.js @@ -0,0 +1,119 @@ +import React, { useContext } from 'react'; +import { GoogleLogin } from "@react-oauth/google"; +import { GoogleOAuthProvider } from "@react-oauth/google"; +import { jwtDecode } from 'jwt-decode'; // 중괄호 없이 임포트 +import { BrowserRouter as Router, Route, Routes, useNavigate, Link } from 'react-router-dom'; // Router를 추가 + +import { createContext, useState } from 'react'; // UserContext를 포함 +import logo from '../logo/white_logo.png' +import '../css/Welcome.css'; // CSS 파일을 import + +// UserContext를 App.js에 직접 정의합니다. +export const UserContext = createContext(); + +const UserProvider = ({ children }) => { + const [user, setUser] = useState(null); + + return ( + + {children} + + ); +}; + +const GoogleLoginPage = () => { + const clientId = "YOUR_CLIENT_ID"; // 본인의 Google Client ID로 대체하세요. + const navigate = useNavigate(); + const { setUser } = useContext(UserContext); + + const handleLogin = async (credentialResponse) => { + const token = credentialResponse.credential; + const decoded = jwtDecode(token); + setUser(decoded); + console.log(decoded); + + try { + const response = await fetch('http://localhost:8000/api/verify', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ token: token }), + }); + if (response.ok) { + const data = await response.json(); + console.log(data); + navigate('/lobby'); + } else { + console.error('Login verification failed'); + } + } catch (error) { + console.error('Error:', error); + } + }; + + return ( + +
+
+

+ MOPIc 로고 +

+ +
+ +
+
+

👨‍🎓 시험 응시료도 만만찮고, 내가 잘하고 있는지도 모르겠어
+ 취업 시장에서 날이 갈수록 중요해지는 영어 시험
+ 5분 정도의 테스트로 내가 어느 정도인지 알아보고, 앞으로 어떻게 해야 할지 파악해 보자!
+ 하루에 딱 5분! 어떤 주제가 나와도 탄탄한 기본기를 쌓으려면? 모픽으로!

+

지금 바로 로그인하기!

+ { + console.log("Login Failed"); + }} + /> +
+
+
+ MOPIc 로고 +
+
+
+ +
+

© 2024 Mopic. All rights reserved.

+
+
+
+ ); +}; + +// Home, About, History 컴포넌트를 간단히 정의 +const Home = () =>

Home Page

; +const About = () =>

About Page

; +const History = () =>

History Page

; + +const App = () => { + return ( + + + + } /> + } /> + } /> + } /> + {/* 추가적인 경로와 컴포넌트를 여기에서 정의할 수 있습니다 */} + + + + ); +}; + +export default App; diff --git a/Re-Frontend/src/css/Welcome.css b/Re-Frontend/src/css/Welcome.css new file mode 100644 index 00000000..bb3bfba4 --- /dev/null +++ b/Re-Frontend/src/css/Welcome.css @@ -0,0 +1,132 @@ +/* 전체 화면 설정 */ +.login-page { + display: flex; + flex-direction: column; + min-height: 100vh; /* 페이지가 전체 화면을 채우도록 설정 */ +} +/* Flexbox로 레이아웃 설정 */ +body { + display: flex; + flex-direction: column; + font-family: 'Arial', sans-serif; + background-color: #d0d0d0; + /* min-height: 100vh; 주석 처리: main의 min-height를 사용하므로 필요하지 않음 */ +} + +/* 헤더 스타일 */ +header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px 20px; + background-color: #6d8d8d; + /* height: 40px; 주석 처리: min-height로 대체 */ + min-height: 5vh; +} + +header h1 { + margin: 0; /* 기본 여백 제거 */ +} + +header img { + width: 100px; /* 로고 크기 조정 */ + height: auto; /* 비율 유지 */ +} + +header nav { + display: flex; +} + +header nav a { + margin: 0 15px; + text-decoration: none; + color: #fff; /* 텍스트 색상 */ + font-size: 16px; +} + +header nav a:hover { + color: #ccc; /* 호버 색상 */ +} + +/* 메인 콘텐츠 스타일 */ +main { + display: flex; + justify-content: space-between; + align-items: stretch; /* 높이 동일하게 맞추기 */ + padding: 10px; /* padding을 줄여서 더 많은 공간 확보 */ + flex: 1; /* 메인 영역이 가변적으로 확장되도록 설정 */ + box-sizing: border-box; /* padding을 포함한 전체 크기 계산 */ + min-height: 85vh; /* 최소 높이를 85% 뷰포트 높이로 설정하여 화면 전체를 채움 */ +} + +/* 콘텐츠와 사이드 콘텐츠를 6:4 비율로 설정 */ +.content { + flex: 6; /* 비율을 위해 너비를 60%로 설정 */ + background-color: #f0f0f0; + padding: 20px; + border-radius: 5px; + box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1); + display: flex; + flex-direction: column; + justify-content: center; /* 내부 아이템의 위치를 중앙으로 조정 */ + text-align: center; /* 텍스트 가운데 정렬 */ + font-size: 20px; +} + +.side-content { + flex: 4; /* 비율을 위해 너비를 40%로 설정 */ + background-color: #C7D9D9; + color: #fff; + padding: 20px; + border-radius: 5px; + box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1); + display: flex; + justify-content: center; /* 가로 중앙 정렬 */ + align-items: center; /* 세로 중앙 정렬 */ + text-align: center; /* 텍스트 가운데 정렬 */ +} + +/* 사이드 콘텐츠의 배경 색상과 텍스트 색상 */ +.side-content { + background-color: #C7D9D9; + color: #fff; +} + +/* 로고 스타일 */ +.logo img { + width: 50%; /* 컨테이너에 맞게 조정 */ + height: auto; /* 비율을 유지하면서 높이를 자동으로 조정 */ + object-fit: contain; /* 이미지의 비율을 유지하면서 컨테이너에 맞게 조정 */ + vertical-align: middle; /* 이미지의 정렬을 조정 */ + +} + + +/* 버튼 스타일 */ +button { + width: 200px; /* 버튼의 너비 */ + padding: 12px 24px; /* 버튼 내부의 여백 (상하좌우) */ + margin-top: 20px; /* 버튼 위의 여백 */ + font-size: 18px; /* 버튼 텍스트의 크기 */ + color: #fff; /* 텍스트 색상 */ + background-color: #333; /* 버튼 배경 색상 */ + border: none; /* 버튼의 테두리 제거 */ + border-radius: 8px; /* 버튼의 모서리 둥글기 */ + cursor: pointer; /* 커서를 포인터로 변경 */ + transition: background-color 0.3s, transform 0.2s; /* 배경색과 크기 변경 시 부드러운 전환 효과 */ + margin: 10px auto; +} +button:hover { + background-color: #555; +} + +/* 푸터 스타일 */ +footer { + padding: 10px 20px; + background-color: #333; + color: #fff; + text-align: center; + height: 40px; /* 푸터 높이 조정 */ + flex-shrink: 0; /* 푸터가 축소되지 않도록 설정 */ + min-height: 5vh; +}