Commit 7bf7b8fa authored by timel's avatar timel

feat: basic card build

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