Commit 7bf7b8fa authored by timel's avatar timel

feat: basic card build

parent 0c5052f5
...@@ -8,33 +8,37 @@ import { Button } from "antd"; ...@@ -8,33 +8,37 @@ import { Button } from "antd";
import styles from "./DeckSelect.module.scss"; import styles from "./DeckSelect.module.scss";
export const DeckSelect: React.FC<{ export const DeckSelect: React.FC<{
decks: { name: string; id: number }[]; decks: readonly { deckName: string }[];
selected: number; selected: string;
onSelect: (id: number) => void; onSelect: (deckName: string) => void;
onDelete: (id: number) => void; onDelete: (deckName: string) => void;
onDownload: (id: number) => void; onDownload: (deckName: string) => void;
onAdd: () => void; onAdd: () => void;
}> = ({ decks, selected, onSelect, onDelete, onDownload, onAdd }) => { }> = ({ decks, selected, onSelect, onDelete, onDownload, onAdd }) => {
return ( return (
<> <>
<div className={styles["deck-select"]}> <div className={styles["deck-select"]}>
{decks.map(({ name, id }) => ( {decks.map(({ deckName }) => (
<div key={id} className={styles.item} onClick={() => onSelect(id)}> <div
key={deckName}
className={styles.item}
onClick={() => onSelect(deckName)}
>
<div className={styles.hover} /> <div className={styles.hover} />
{selected === id && <div className={styles.selected} />} {selected === deckName && <div className={styles.selected} />}
<span>{name}</span> <span>{deckName}</span>
<div className={styles.btns}> <div className={styles.btns}>
<Button <Button
icon={<DeleteOutlined />} icon={<DeleteOutlined />}
type="text" type="text"
size="small" size="small"
onClick={cancelBubble(() => onDelete(id))} onClick={cancelBubble(() => onDelete(deckName))}
/> />
<Button <Button
icon={<DownloadOutlined />} icon={<DownloadOutlined />}
type="text" type="text"
size="small" size="small"
onClick={cancelBubble(() => onDownload(id))} onClick={cancelBubble(() => onDownload(deckName))}
/> />
</div> </div>
</div> </div>
......
...@@ -15,8 +15,12 @@ import { ...@@ -15,8 +15,12 @@ import {
Space, Space,
type ThemeConfig, type ThemeConfig,
} from "antd"; } from "antd";
import { useEffect, useState } from "react";
import { useSnapshot } from "valtio";
import { Background } from "../Shared"; import { deckStore, type IDeck } from "@/stores";
import { Background, YgoCard } from "@/ui/Shared";
import { CardDetail } from "./CardDetail"; import { CardDetail } from "./CardDetail";
import { DeckSelect } from "./DeckSelect"; import { DeckSelect } from "./DeckSelect";
import styles from "./index.module.scss"; import styles from "./index.module.scss";
...@@ -30,6 +34,9 @@ const theme: ThemeConfig = { ...@@ -30,6 +34,9 @@ const theme: ThemeConfig = {
}; };
export const Component: React.FC = () => { export const Component: React.FC = () => {
const snapDecks = useSnapshot(deckStore);
const [selectedDeck, setSelectedDeck] = useState<IDeck>(deckStore.decks[0]);
return ( return (
<ConfigProvider theme={theme}> <ConfigProvider theme={theme}>
<Background /> <Background />
...@@ -37,12 +44,11 @@ export const Component: React.FC = () => { ...@@ -37,12 +44,11 @@ export const Component: React.FC = () => {
<div className={styles.sider}> <div className={styles.sider}>
<div className={styles["deck-select-container"]}> <div className={styles["deck-select-container"]}>
<DeckSelect <DeckSelect
decks={Array.from({ length: 18 }).map((_, i) => ({ decks={snapDecks.decks}
name: `卡组 ${i}`, selected={selectedDeck.deckName}
id: i, onSelect={(name) =>
}))} setSelectedDeck(deckStore.get(name) ?? deckStore.decks[0])
selected={4} }
onSelect={(id) => console.log(id)}
onDelete={(id) => console.log(id)} onDelete={(id) => console.log(id)}
onDownload={(id) => console.log(id)} onDownload={(id) => console.log(id)}
onAdd={() => console.log("add")} onAdd={() => console.log("add")}
...@@ -51,7 +57,7 @@ export const Component: React.FC = () => { ...@@ -51,7 +57,7 @@ export const Component: React.FC = () => {
<CardDetail code={123} open={false} onClose={() => {}} /> <CardDetail code={123} open={false} onClose={() => {}} />
</div> </div>
<div className={styles.content}> <div className={styles.content}>
<Deck /> <Deck deck={selectedDeck} onSave={() => {}} />
<CardSelect /> <CardSelect />
</div> </div>
</div> </div>
...@@ -61,16 +67,27 @@ export const Component: React.FC = () => { ...@@ -61,16 +67,27 @@ export const Component: React.FC = () => {
Component.displayName = "Build"; Component.displayName = "Build";
/** 正在编辑的卡组 */ /** 正在编辑的卡组 */
const Deck: React.FC = () => { const Deck: React.FC<{
deck: IDeck;
onSave: (deck: IDeck) => void;
}> = ({ deck, onSave }) => {
const [editingDeck, setEditingDeck] = useState<IDeck>(deck);
useEffect(() => {
setEditingDeck(deck);
}, [deck]);
return ( return (
<div className={styles.deck}> <div className={styles.deck}>
<div className={styles.container}> <div className={styles.container}>
<Space className={styles.title}> <Space className={styles.title}>
<Input <Input
placeholder="我的卡组" placeholder="请输入卡组名字"
bordered={false} bordered={false}
prefix={<EditOutlined />} prefix={<EditOutlined />}
style={{ width: 400 }} style={{ width: 400 }}
onChange={(e) =>
setEditingDeck({ ...editingDeck, deckName: e.target.value })
}
value={editingDeck.deckName}
/> />
<Space style={{ marginRight: 6 }}> <Space style={{ marginRight: 6 }}>
<Button type="text" size="small" icon={<DeleteOutlined />}> <Button type="text" size="small" icon={<DeleteOutlined />}>
...@@ -79,36 +96,31 @@ const Deck: React.FC = () => { ...@@ -79,36 +96,31 @@ const Deck: React.FC = () => {
<Button type="text" size="small" icon={<UndoOutlined />}> <Button type="text" size="small" icon={<UndoOutlined />}>
重置 重置
</Button> </Button>
<Button type="text" size="small" icon={<CheckOutlined />}> <Button
type="text"
size="small"
icon={<CheckOutlined />}
onClick={() => onSave(editingDeck)}
>
保存 保存
</Button> </Button>
</Space> </Space>
</Space> </Space>
<div className={styles["deck-zone"]}> <div className={styles["deck-zone"]}>
<div className={styles.main}> {(["main", "extra", "side"] as const).map((type) => (
<div className={styles[type]}>
<div className={styles["card-continer"]}> <div className={styles["card-continer"]}>
{Array.from({ length: 42 }).map((_, i) => ( {editingDeck[type].map((code, i) => (
<div className={styles.card} key={i} /> <div className={styles.card} key={i}>
))} <YgoCard code={code} />
</div>
</div> </div>
<div className={styles.extra}>
<div className={styles["card-continer"]}>
{Array.from({ length: 15 }).map((_, i) => (
<div className={styles.card} key={i} />
))} ))}
</div> </div>
</div> </div>
<div className={styles.side}>
<div className={styles["card-continer"]}>
{Array.from({ length: 15 }).map((_, i) => (
<div className={styles.card} key={i} />
))} ))}
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
); );
}; };
......
...@@ -15,10 +15,10 @@ import styles from "./index.module.scss"; ...@@ -15,10 +15,10 @@ import styles from "./index.module.scss";
const NeosConfig = useConfig(); const NeosConfig = useConfig();
export const loader: LoaderFunction = () => { export const loader: LoaderFunction = async () => {
const user = getCookie<User>(CookieKeys.USER); const user = getCookie<User>(CookieKeys.USER);
if (user) accountStore.login(user); if (user) accountStore.login(user);
deckStore.initialize(); await deckStore.initialize();
return null; return null;
}; };
......
import { createBrowserRouter, RouterProvider } from "react-router-dom"; import { createBrowserRouter, RouterProvider } from "react-router-dom";
import { Component, loader } from "./Layout";
const router = createBrowserRouter([ const router = createBrowserRouter([
{ {
path: "/", path: "/",
lazy: () => import("./Layout"), Component,
loader,
children: [ children: [
{ {
path: "/", path: "/",
......
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