Commit 288d456c authored by timel's avatar timel

feat: match page

parent 294d0f81
Pipeline #22887 failed with stages
in 12 minutes and 29 seconds
......@@ -34,7 +34,10 @@ const theme: ThemeConfig = {
export const Component: React.FC = () => {
return (
<ConfigProvider theme={theme}>
<Background />
<Background
style={{ backgroundImage: "initial" }}
innerStyle={{ background: "rgba(72, 0, 255, 0.6)" }}
/>
<div className={styles.layout} style={{ width: "100%" }}>
<div className={styles.sider}>
<div className={styles["deck-select-container"]}>
......
......@@ -10,7 +10,7 @@
display: flex;
flex-direction: column;
align-items: center;
gap: 75px;
gap: 60px;
}
}
......@@ -31,7 +31,7 @@
border-right: none;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
background-color: rgba(255, 255, 255, 0.08);
background-color: rgba(255, 255, 255, 0.04);
}
.select :global(.ant-select-selector) {
border-top-left-radius: 0;
......@@ -45,33 +45,57 @@
.mode-select {
display: grid;
grid-template-columns: 1fr 1fr 1.75fr; /* 三列 */
grid-template-rows: auto; /* 自动调整行高 */
gap: 40px 34px; /* 行和列的间隔 */
width: 1000px;
height: 414px;
.rank {
grid-column: 1 / 2;
grid-row: 1 / 3;
}
.fun {
grid-column: 2 / 3;
grid-row: 1 / 3;
}
.solo {
grid-column: 3 / 4;
}
.custom {
grid-column: 3 / 4;
}
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr); /* 自动调整行高 */
width: 800px;
height: 500px;
gap: 16px;
.mode {
height: -webkit-fill-available;
border-radius: 20px;
background: linear-gradient(
180deg,
rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 0.05) 100%
);
border: 1px solid rgba(255, 255, 255, 0.2);
height: 100%;
background: hsla(0, 0%, 100%, 0.05);
backdrop-filter: blur(10px);
padding: 32px;
border-radius: 12px;
transition: 0.2s;
cursor: pointer;
&:hover {
box-shadow: 0 0 0 4px rgb(56, 27, 143);
background: hsla(0, 0%, 100%, 0.07);
filter: brightness(1.1);
}
.icon {
&::before {
content: "";
width: 100%;
height: 100%;
position: absolute;
background: linear-gradient(#514f5780, #2a283277);
}
overflow: hidden;
position: relative;
--length: 48px;
width: var(--length);
height: var(--length);
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
color: white;
transition: 0.2s;
}
&:hover .icon {
filter: brightness(1.3);
}
.title {
margin-top: 24px;
margin-bottom: 12px;
font-size: 16px;
}
.desc {
font-size: 14px;
line-height: 24px;
color: hsla(0, 0%, 100%, 0.6);
}
}
}
......@@ -4,10 +4,14 @@ import { type LoaderFunction } from "react-router-dom";
import { CookieKeys, setCookie } from "@/api";
import { accountStore, type User } from "@/stores";
import { Background } from "@/ui/Shared";
import { Background, IconFont } from "@/ui/Shared";
import { useConfig } from "@/config";
import { SettingFilled, EditFilled } from "@ant-design/icons";
import styles from "./index.module.scss";
const NeosConfig = useConfig();
export const loader: LoaderFunction = () => {
const sso = new URLSearchParams(location.search).get("sso");
const user = sso ? getSSOUser(new URLSearchParams(atob(sso))) : undefined;
......@@ -28,7 +32,7 @@ export const Component: React.FC = () => {
<CustomSelect
title="服务器"
defaultValue="lucy"
style={{ width: 370 }}
style={{ width: 200 }}
options={[
{ value: "jack", label: "Jack" },
{ value: "lucy", label: "Lucy" },
......@@ -40,7 +44,7 @@ export const Component: React.FC = () => {
title="卡组"
showSearch
defaultValue="lucy"
style={{ width: 370 }}
style={{ width: 200 }}
options={[
{ value: "jack", label: "Jack" },
{ value: "lucy", label: "Lucy" },
......@@ -50,12 +54,36 @@ export const Component: React.FC = () => {
/>
</Space>
<div className={styles["mode-select"]}>
<div className={classNames(styles.mode, styles.rank)}>竞技匹配</div>
<div className={classNames(styles.mode, styles.fun)}>娱乐匹配</div>
<div className={classNames(styles.mode, styles.solo)}>单人模式</div>
<div className={classNames(styles.mode, styles.custom)}>
自定义房间
</div>
<Mode
title="竞技匹配"
desc="与世界上其他玩家在线匹配,您的排名将实时显示在排行榜上。"
icon={<IconFont type="icon-battle" size={32} />}
/>
<Mode
title="休闲匹配"
desc="使用任意卡组进行对战,将胜负暂且搁置,尽情享受决斗的乐趣。"
icon={<IconFont type="icon-coffee" size={28} />}
/>
<Mode
title="单人模式"
desc="开启与AI的决斗,验证自己的卡组,或者只是打发时间。"
icon={<IconFont type="icon-chip" size={26} />}
/>
<Mode
title="自定义房间"
desc="创建一个自定义的对战房间,便捷地与好友进行对战,甚至是举办一场竞技比赛。"
icon={<SettingFilled />}
/>
<Mode
title="录像回放"
desc="自由查看进行过的决斗,回味那些精彩的逆转瞬间。"
icon={<IconFont type="icon-record" size={24} />}
/>
<Mode
title="卡组编辑"
desc="创建和编辑卡组,在上万种卡片中选择,组建独一无二的构筑。"
icon={<EditFilled />}
/>
</div>
</div>
</main>
......@@ -64,6 +92,18 @@ export const Component: React.FC = () => {
};
Component.displayName = "Match";
const Mode: React.FC<{
title: string;
desc: string;
icon: React.ReactNode;
}> = ({ title, desc, icon }) => (
<div className={styles.mode}>
<div className={styles.icon}>{icon}</div>
<div className={styles.title}>{title}</div>
<div className={styles.desc}>{desc}</div>
</div>
);
/** 从SSO跳转回的URL之中,解析用户信息 */
function getSSOUser(searchParams: URLSearchParams): User {
return Object.fromEntries(searchParams) as unknown as User;
......
......@@ -7,6 +7,7 @@
overflow: hidden;
width: 100%;
background-color: #010514;
background-image: url("/neos-assets/background-grid.webp");
z-index: -1;
display: flex;
justify-content: center;
......@@ -16,6 +17,6 @@
.inner {
width: 90vw;
height: 50vh;
background: rgba(72, 0, 255, 0.6);
background: rgba(72, 0, 255, 0.8);
filter: blur(582px);
}
import { createFromIconfontCN } from "@ant-design/icons";
const _IconFont = createFromIconfontCN({
scriptUrl: ["//at.alicdn.com/t/c/font_4188978_14gvq0ry2bk.js"],
scriptUrl: ["//at.alicdn.com/t/c/font_4188978_evr8efp70uk.js"],
});
export const IconFont: React.FC<{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment