Files
LP_Bot/src/pages/LoginPage.tsx

159 lines
5.2 KiB
TypeScript
Raw Normal View History

2025-12-08 15:50:23 +08:00
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>
);
}