Spare cards is always last

Also add warning if no cards were added
pull/113/head
火焚 富良 2024-01-05 17:22:53 +08:00 committed by Egor Savkin
parent a589c309cc
commit 963f342c89
9 changed files with 96 additions and 46 deletions

View File

@ -11,6 +11,18 @@
.feedback-add-success {
display: none;
}
.feedback-add-failure {
background-color: #c75e5e;
display: block;
position: fixed;
top: 20px;
right: 20px;
padding: 1em;
z-index: 100000;
color: white;
border-radius: 10px;
box-shadow: 0 0 5px 3px;
}
#accordion_categories,
#accordion_categories .accordion-header,
@ -251,7 +263,7 @@
##Screen = B/w 481px to 767px
*/
@media (min-width: 481px) and (max-width: 767px) {
.feedback-add-success {
.feedback-add-success, .feedback-add-failure {
background-color: green;
display: block;
position: fixed;
@ -263,6 +275,9 @@
border-radius: 10px;
box-shadow: 0 0 5px 3px;
}
.feedback-add-failure {
background-color: #c75e5e;
}
.dropdown-item {
font-size: .75em;
@ -459,7 +474,7 @@
##Screen = B/w 320px to 479px
*/
@media (min-width: 320px) and (max-width: 480px) {
.feedback-add-success {
.feedback-add-success, .feedback-add-failure {
background-color: green;
display: block;
position: fixed;
@ -471,6 +486,9 @@
border-radius: 10px;
box-shadow: 0 0 5px 3px;
}
.feedback-add-failure {
background-color: #c75e5e;
}
.dropdown-item {
font-size: .75em;

File diff suppressed because one or more lines are too long

View File

@ -4,6 +4,5 @@ import React from "react";
import { createRoot } from "react-dom/client";
import { Shop } from "./shop/Shop.jsx"
import { data } from "./shop/utils"
createRoot(document.querySelector('#root-shop')).render(<Shop data={data} />);
createRoot(document.querySelector('#root-shop')).render(<Shop />);

View File

@ -16,19 +16,21 @@ export function CrateList() {
const onAddCrate = useShopStore((state) => state.newCrate);
const setActiveCrate = useShopStore((state) => state.setActiveCrate);
const onSelectHandler = (e) => {
// if e === null, that means that an accordion item was collapsed rather than expanded. e will be non-null when an item is expanded
if (e !== null)
setActiveCrate(e);
else
setActiveCrate("")
};
// #!render_count
console.log("CrateList renders: ", renderCount)
return (
<Accordion id="accordion_crates" flush activeKey={active_crate} onSelect={(e) => {
// if e === null, that means that an accordion item was collapsed rather than expanded. e will be non-null when an item is expanded
if (e !== null)
setActiveCrate(e);
else
setActiveCrate("")
}}>
<Accordion id="accordion_crates" flush activeKey={active_crate} onSelect={onSelectHandler}>
{crates.map((crate, index) =>
<Accordion.Item eventKey={crate.id} key={"accordion"+crate.id} className="accordion_crates_item">
<Accordion.Header>Crate #{`${index}`}</Accordion.Header>
<Accordion.Header>{crate.name ? crate.name : <>Crate #{`${index}`}</>} </Accordion.Header>
<Accordion.Body>
<Crate crate_index={index}/>
</Accordion.Body>

View File

@ -19,16 +19,20 @@ export function CrateMode({crate_index}) {
// #!render_count
console.log("CrateMode renders: ", renderCount)
return (
<div className="crate-mode">
{modes_order.map((mode_name, _) => (
<a
key={mode_name}
className={(crate.crate_mode === mode_name ? 'active' : '') }
onClick={() => setMode(crate.id, mode_name)}
href="#"
role="button">{crate_modes[mode_name].name}</a>
))}
</div>
);
if (modes_order.includes(crate.crate_mode)) {
return (
<div className="crate-mode">
{modes_order.map((mode_name, _) => (
<a
key={mode_name}
className={(crate.crate_mode === mode_name ? 'active' : '')}
onClick={() => setMode(crate.id, mode_name)}
href="#"
role="button">{crate_modes[mode_name].name}</a>
))}
</div>
);
} else {
return <div className="crate-mode"></div>
}
}

View File

@ -16,26 +16,31 @@ export function Layout({aside, main}) {
const mobileSideMenuShouldOpen = useShopStore(state => state.sideMenuIsOpen);
const onClickToggleMobileSideMenu = useShopStore(state => state.switchSideMenu);
const showCardAddedFeedback = useShopStore(state => state.showCardAddedFeedback);
const showNoDestination = useShopStore(state => state.showNoDestination);
// #!render_count
console.log("Layout renders: ", renderCount)
return (
<div className="layout">
<div className="layout">
<aside className={'aside ' + (mobileSideMenuShouldOpen ? 'menu-opened' : '')}>{aside}</aside>
<aside className={'aside ' + (mobileSideMenuShouldOpen ? 'menu-opened' : '')}>{aside}</aside>
{mobileSideMenuShouldOpen ? (
<section className="main" onClick={onClickToggleMobileSideMenu}>{main}</section>
) : (
<section className="main">{main}</section>
)}
{mobileSideMenuShouldOpen ? (
<section className="main" onClick={onClickToggleMobileSideMenu}>{main}</section>
) : (
<section className="main">{main}</section>
)}
{showCardAddedFeedback ? (
<div className="feedback-add-success">
{showCardAddedFeedback ? (
!showNoDestination ?
(<div className="feedback-add-success">
added
</div>
) : null}
</div>
);
</div>)
: (<div className="feedback-add-failure">
No cards added: all crates are closed
</div>)
) : null}
</div>
);
}

View File

@ -39,6 +39,7 @@ const useLayout = ((set, get) => ({
isMobile: window.deviceIsMobile(),
sideMenuIsOpen: false,
showCardAddedFeedback: false,
showNoDestination: false,
timerAdded: null,
switchSideMenu: () => set(state => ({
@ -46,10 +47,18 @@ const useLayout = ((set, get) => ({
})),
cardAdded: () => set(state => ({
showCardAddedFeedback: true,
showNoDestination: false,
timerAdded: (!!state.timerAdded ? clearTimeout(state.timerAdded) : null) || (state.isMobile && setTimeout(() => {
get()._endCardAdded()
}, 2000))
})),
noDestinationWarning: () => set(state => ({
showCardAddedFeedback: true,
showNoDestination: true,
timerAdded: (!!state.timerAdded ? clearTimeout(state.timerAdded) : null) || (setTimeout(() => {
get()._endCardAdded()
}, 2000))
})),
_endCardAdded: () => set(state => ({
showCardAddedFeedback: false,
timerAdded: !!state.timerAdded ? clearTimeout(state.timerAdded) : null
@ -221,7 +230,7 @@ const useCart = ((set, get) => ({
active_crate: "crate0",
_newCrate: (crate_id) => set((state) => ({
crates: state.crates.concat({
crates: state.crates.toSpliced(-1, 0, {
id: crate_id || "crate" + state.crates.length,
crate_mode: "rack",
items: [],
@ -403,7 +412,11 @@ const useCart = ((set, get) => ({
addCardFromBacklog: (crate_to, index_from, index_to, just_mounted) => {
const dest = crate_to || get().active_crate;
if (!dest) return {};
if (!dest) {
console.warn("No destination");
get().noDestinationWarning();
return {};
}
get()._addCardFromBacklog(dest, index_from, index_to)
get().fillExtData(dest);
get().fillWarnings(dest);

View File

@ -25,7 +25,7 @@ const shop_data = {
}
},
crateModeOrder: [
"rack", "desktop", "no_crate"
"rack", "desktop"
],
items: {
@ -1156,7 +1156,16 @@ const shop_data = {
items: [],
warnings: [],
occupiedHP: 0,
}]
},
{
id: "spare",
name: "Spare cards",
crate_mode: "no_crate",
items: [],
warnings: [],
occupiedHP: 0,
}
]
},
};

View File

@ -37,8 +37,8 @@ module.exports = {
resolve: {
extensions: ['.tsx', '.ts', '.js', '.jsx'],
},
devtool: "inline-source-map",
mode: "development"
//devtool: false,
//mode: "production"
//devtool: "inline-source-map",
//mode: "development"
devtool: false,
mode: "production"
};