159 lines
5.2 KiB
TypeScript
159 lines
5.2 KiB
TypeScript
import BusinessTypeSetting from "@/_BusinessTypeSetting/BusinessTypeSetting";
|
||
import MainControlData from "@/Common/DataReceived/MainControlData";
|
||
import GameManager from "@/modules/GameManager";
|
||
import React, { useContext, useEffect, useState } from "react";
|
||
import { useNavigate } from "react-router-dom";
|
||
import MainControl, { DownloadForm } from "../Common/MainControl/MainControl";
|
||
import CSMessage from "../Common/Message/CSMessage";
|
||
import { GameItemsContext } from "../context/GameItemsContext";
|
||
import { AccountLoginRequest, CommonAccountResponse, LineLoginRequest } from "../define/Request/AccountRequest";
|
||
import { CoroutineV2 } from "../Engine/CatanEngine/CoroutineV2/CoroutineV2";
|
||
import { INetResponse } from "../Engine/CatanEngine/NetManagerV2/Core/INetResponse";
|
||
|
||
export default function LoginPage() {
|
||
const navigate = useNavigate();
|
||
const { player, setPlayer } = useContext(GameItemsContext);
|
||
|
||
const [server, setServer] = useState("https://dev.lybobet.com");
|
||
const [port, setPort] = useState("9005");
|
||
const [token, setToken] = useState("");
|
||
const [loading, setLoading] = useState(false);
|
||
|
||
useEffect(() => {
|
||
if (!MainControl.Instance) new MainControl();
|
||
new MainControlData();
|
||
new GameManager();
|
||
const savedToken = localStorage.getItem("token");
|
||
if (savedToken) setToken(savedToken);
|
||
|
||
// DownloadForm
|
||
MainControl.DownloadForm(DownloadForm.FormType.Formread)
|
||
}, []);
|
||
|
||
const handleChange = (setter: any) => (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) =>
|
||
setter(e.target.value);
|
||
|
||
const onClickLogin = async () => {
|
||
if (!server) return CSMessage.CreateYesMsg("請輸入 server");
|
||
if (!port) return CSMessage.CreateYesMsg("請輸入 port");
|
||
if (!token) return CSMessage.CreateYesMsg("請輸入 token");
|
||
if (loading) return;
|
||
|
||
setLoading(true);
|
||
BusinessTypeSetting.UseHost = server;
|
||
BusinessTypeSetting.UsePort = +port;
|
||
CoroutineV2.Single(login()).Start();
|
||
};
|
||
|
||
function* login() {
|
||
try {
|
||
localStorage.setItem("token", token);
|
||
yield* MainControl.Instance.ConnectAsync(BusinessTypeSetting.UseHost, BusinessTypeSetting.UsePort);
|
||
yield* registerLineLogin();
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
}
|
||
|
||
function* registerLineLogin() {
|
||
const req = new LineLoginRequest(token);
|
||
yield req.SendAsync(true);
|
||
const resp: INetResponse<CommonAccountResponse> = req.Result;
|
||
|
||
if (!resp.IsValid) {
|
||
if (resp.Status !== 12) CSMessage.CreateYesMsg("Line Info Error. Error Code: " + resp.Status);
|
||
else console.warn("LINE帳號無綁定");
|
||
return;
|
||
}
|
||
|
||
yield* serverAccountLogin(resp.Data.id, resp.Data.pw);
|
||
}
|
||
|
||
function* serverAccountLogin(a: string, pw: string, partner: string | null = null): IterableIterator<any> {
|
||
const hasAP = a && a !== "null" && a !== "undefined" && pw && pw !== "null" && pw !== "undefined";
|
||
if (!hasAP) return CSMessage.CreateYesMsg("沒有帳號或密碼.請確認回傳接值.");
|
||
|
||
const req = new AccountLoginRequest(a, pw, partner);
|
||
yield req.SendAsync(true);
|
||
const resp: INetResponse<any> = req.Result;
|
||
|
||
if (!resp.IsValid) return CSMessage.CreateYesMsg("Login Account Error! Error Code : " + resp.Status);
|
||
|
||
setPlayer({ ...player, ...resp.Data, token });
|
||
navigate("/lobby");
|
||
}
|
||
|
||
// ====== inline CSS ======
|
||
const containerStyle: React.CSSProperties = {
|
||
height: "100vh",
|
||
display: "flex",
|
||
justifyContent: "center",
|
||
alignItems: "center",
|
||
background: "transparent",
|
||
padding: "16px",
|
||
color: "#000000", // 文字黑色
|
||
};
|
||
|
||
const boxStyle: React.CSSProperties = {
|
||
background: "white", // 卡片內部保持白色
|
||
padding: "24px",
|
||
borderRadius: "16px",
|
||
width: "100%",
|
||
maxWidth: "400px",
|
||
boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
|
||
display: "flex",
|
||
flexDirection: "column",
|
||
gap: "16px",
|
||
color: "#000000", // 卡片內文字黑色
|
||
};
|
||
|
||
const inputStyle: React.CSSProperties = {
|
||
width: "100%",
|
||
padding: "12px",
|
||
borderRadius: "12px",
|
||
border: "1px solid #d9d9d9",
|
||
fontSize: "1rem",
|
||
color: "#000000", // 輸入文字黑色
|
||
backgroundColor: "#ffffff", // 輸入框白色
|
||
};
|
||
|
||
const buttonStyle: React.CSSProperties = {
|
||
width: "100%",
|
||
padding: "12px",
|
||
borderRadius: "12px",
|
||
border: "none",
|
||
backgroundColor: loading ? "#a0a0a0" : "#1890ff",
|
||
color: "white",
|
||
cursor: loading ? "not-allowed" : "pointer",
|
||
fontSize: "1rem",
|
||
transition: "all 0.3s",
|
||
};
|
||
|
||
return (
|
||
<div style={containerStyle}>
|
||
<div style={boxStyle}>
|
||
<h1 style={{ textAlign: "center", fontSize: "1.8rem", margin: 0 }}>登入</h1>
|
||
|
||
<div style={{ display: "flex", flexDirection: "column", gap: "8px" }}>
|
||
<label>Server:</label>
|
||
<input style={inputStyle} value={server} onChange={handleChange(setServer)} placeholder="例如:http://192.168.1.10" />
|
||
</div>
|
||
|
||
<div style={{ display: "flex", flexDirection: "column", gap: "8px" }}>
|
||
<label>Port:</label>
|
||
<input style={inputStyle} value={port} onChange={handleChange(setPort)} placeholder="9005" />
|
||
</div>
|
||
|
||
<div style={{ display: "flex", flexDirection: "column", gap: "8px" }}>
|
||
<label>Token:</label>
|
||
<textarea style={{ ...inputStyle, height: "80px" }} value={token} onChange={handleChange(setToken)} placeholder="輸入 Token" />
|
||
</div>
|
||
|
||
<button style={buttonStyle} onClick={onClickLogin} disabled={loading}>
|
||
{loading ? "登入中..." : "登入"}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|